From 47c1a1a109b7d9f72d62feaca663fa5aaf96fda9 Mon Sep 17 00:00:00 2001
From: Ww67652 <1749113286@qq.com>
Date: Sun, 29 Sep 2024 15:24:52 +0800
Subject: [PATCH 01/11] update: service for v2 protocol (ConfigService)

---
 config_server/service/.gitignore              |    6 +-
 config_server/service/Dockerfile              |   38 +-
 config_server/service/Dockerfile-dev          |   13 +
 config_server/service/README.md               |   69 +
 .../cmd/config/prod/databaseConfig.json       |    9 +
 .../service/cmd/config/prod/serverConfig.json |   14 +
 config_server/service/cmd/env.json            |    3 +
 config_server/service/cmd/main.go             |   16 +
 config_server/service/common/data_type.go     |   23 -
 config_server/service/common/http_response.go |   35 -
 config_server/service/common/json_file.go     |   64 -
 config_server/service/common/queue.go         |   84 -
 config_server/service/example/setting.json    |    8 -
 config_server/service/go.mod                  |   70 +-
 config_server/service/go.sum                  |  171 +-
 .../interface/agent/collection_config.go      |   62 -
 .../service/interface/agent/status.go         |   52 -
 .../service/interface/user/agent_group.go     |  229 ---
 .../interface/user/collection_config.go       |  165 --
 .../service/internal/common/api_error.go      |   63 +
 .../service/internal/common/http_status.go    |   25 +
 config_server/service/internal/common/log.go  |   11 +
 .../service/internal/common/result.go         |   26 +
 config_server/service/internal/config/gorm.go |   92 +
 .../service/internal/config/server.go         |   43 +
 .../service/internal/entity/agent.go          |  111 +
 .../internal/entity/agent_and_config.go       |   81 +
 .../service/internal/entity/agent_group.go    |   33 +
 config_server/service/internal/entity/base.go |   18 +
 .../service/internal/entity/command.go        |   14 +
 .../service/internal/entity/config.go         |   75 +
 .../service/internal/handler/agent.go         |  158 ++
 .../service/internal/handler/agent_group.go   |  181 ++
 .../internal/handler/instance_config.go       |  201 ++
 .../internal/handler/pipeline_config.go       |  203 ++
 .../service/internal/manager/agent.go         |   43 +
 .../service/internal/manager/agent_group.go   |   87 +
 .../internal/manager/capability/agent.go      |   88 +
 .../internal/manager/capability/common.go     |   23 +
 .../internal/manager/capability/server.go     |  112 ++
 .../service/internal/manager/config.go        |   54 +
 .../service/internal/manager/flag/request.go  |   60 +
 .../service/internal/manager/flag/response.go |  100 +
 .../service/internal/protov2/agent.pb.go      | 1531 ++++++++++++++
 .../{proto => internal/protov2}/user.pb.go    | 1789 ++++++++---------
 .../service/internal/repository/agent.go      |   89 +
 .../internal/repository/agent_group.go        |   90 +
 .../service/internal/repository/base.go       |   44 +
 .../service/internal/repository/config.go     |   44 +
 .../internal/repository/instance_config.go    |  117 ++
 .../internal/repository/pipeline_config.go    |  115 ++
 .../service/internal/router/router.go         |   70 +
 .../service/internal/router/router_test.go    |   75 +
 .../service/internal/service/agent.go         |  174 ++
 .../service/internal/service/agent_group.go   |  114 ++
 .../internal/service/instance_config.go       |  149 ++
 .../internal/service/pipeline_config.go       |  153 ++
 config_server/service/internal/store/gorm.go  |  171 ++
 .../service/internal/store/gorm_test.go       |   13 +
 config_server/service/internal/store/store.go |    8 +
 .../service/internal/utils/environment.go     |   29 +
 config_server/service/internal/utils/json.go  |   28 +
 config_server/service/internal/utils/list.go  |   40 +
 config_server/service/internal/utils/str.go   |    7 +
 config_server/service/internal/utils/task.go  |   56 +
 .../service/manager/agent/agent_manager.go    |   56 -
 .../service/manager/agent/agent_operator.go   |   75 -
 .../service/manager/config/agent_operator.go  |  232 ---
 .../service/manager/config/config_manager.go  |   54 -
 .../service/manager/config/user_operator.go   |  691 -------
 config_server/service/manager/manager.go      |   39 -
 config_server/service/model/agent.go          |  140 --
 config_server/service/model/agent_group.go    |  101 -
 .../service/model/collection_config.go        |   79 -
 config_server/service/model/model_type.go     |   36 -
 config_server/service/proto/agent.pb.go       | 1473 --------------
 config_server/service/router/router.go        |   68 -
 config_server/service/service.go              |   25 -
 .../service/setting/mysql-setting.json        |   11 -
 config_server/service/setting/setting.go      |  104 -
 config_server/service/setting/setting.json    |    8 -
 .../service/setting/sqlite-setting.json       |   10 -
 config_server/service/store/gorm/gorm.go      |  273 ---
 .../interface_database/interface_database.go  |   80 -
 .../service/store/leveldb/leveldb.go          |  221 --
 config_server/service/store/store.go          |   63 -
 config_server/service/test/interface_test.go  | 1231 ------------
 config_server/service/test/request.go         |  323 ---
 .../service/test/setting/setting.json         |    1 -
 config_server/service/test/setting_test.go    |   37 -
 config_server/service/test/store_test.go      |   68 -
 91 files changed, 6137 insertions(+), 7301 deletions(-)
 create mode 100644 config_server/service/Dockerfile-dev
 create mode 100644 config_server/service/README.md
 create mode 100644 config_server/service/cmd/config/prod/databaseConfig.json
 create mode 100644 config_server/service/cmd/config/prod/serverConfig.json
 create mode 100644 config_server/service/cmd/env.json
 create mode 100644 config_server/service/cmd/main.go
 delete mode 100644 config_server/service/common/data_type.go
 delete mode 100644 config_server/service/common/http_response.go
 delete mode 100644 config_server/service/common/json_file.go
 delete mode 100644 config_server/service/common/queue.go
 delete mode 100644 config_server/service/example/setting.json
 delete mode 100644 config_server/service/interface/agent/collection_config.go
 delete mode 100644 config_server/service/interface/agent/status.go
 delete mode 100644 config_server/service/interface/user/agent_group.go
 delete mode 100644 config_server/service/interface/user/collection_config.go
 create mode 100644 config_server/service/internal/common/api_error.go
 create mode 100644 config_server/service/internal/common/http_status.go
 create mode 100644 config_server/service/internal/common/log.go
 create mode 100644 config_server/service/internal/common/result.go
 create mode 100644 config_server/service/internal/config/gorm.go
 create mode 100644 config_server/service/internal/config/server.go
 create mode 100644 config_server/service/internal/entity/agent.go
 create mode 100644 config_server/service/internal/entity/agent_and_config.go
 create mode 100644 config_server/service/internal/entity/agent_group.go
 create mode 100644 config_server/service/internal/entity/base.go
 create mode 100644 config_server/service/internal/entity/command.go
 create mode 100644 config_server/service/internal/entity/config.go
 create mode 100644 config_server/service/internal/handler/agent.go
 create mode 100644 config_server/service/internal/handler/agent_group.go
 create mode 100644 config_server/service/internal/handler/instance_config.go
 create mode 100644 config_server/service/internal/handler/pipeline_config.go
 create mode 100644 config_server/service/internal/manager/agent.go
 create mode 100644 config_server/service/internal/manager/agent_group.go
 create mode 100644 config_server/service/internal/manager/capability/agent.go
 create mode 100644 config_server/service/internal/manager/capability/common.go
 create mode 100644 config_server/service/internal/manager/capability/server.go
 create mode 100644 config_server/service/internal/manager/config.go
 create mode 100644 config_server/service/internal/manager/flag/request.go
 create mode 100644 config_server/service/internal/manager/flag/response.go
 create mode 100644 config_server/service/internal/protov2/agent.pb.go
 rename config_server/service/{proto => internal/protov2}/user.pb.go (51%)
 create mode 100644 config_server/service/internal/repository/agent.go
 create mode 100644 config_server/service/internal/repository/agent_group.go
 create mode 100644 config_server/service/internal/repository/base.go
 create mode 100644 config_server/service/internal/repository/config.go
 create mode 100644 config_server/service/internal/repository/instance_config.go
 create mode 100644 config_server/service/internal/repository/pipeline_config.go
 create mode 100644 config_server/service/internal/router/router.go
 create mode 100644 config_server/service/internal/router/router_test.go
 create mode 100644 config_server/service/internal/service/agent.go
 create mode 100644 config_server/service/internal/service/agent_group.go
 create mode 100644 config_server/service/internal/service/instance_config.go
 create mode 100644 config_server/service/internal/service/pipeline_config.go
 create mode 100644 config_server/service/internal/store/gorm.go
 create mode 100644 config_server/service/internal/store/gorm_test.go
 create mode 100644 config_server/service/internal/store/store.go
 create mode 100644 config_server/service/internal/utils/environment.go
 create mode 100644 config_server/service/internal/utils/json.go
 create mode 100644 config_server/service/internal/utils/list.go
 create mode 100644 config_server/service/internal/utils/str.go
 create mode 100644 config_server/service/internal/utils/task.go
 delete mode 100644 config_server/service/manager/agent/agent_manager.go
 delete mode 100644 config_server/service/manager/agent/agent_operator.go
 delete mode 100644 config_server/service/manager/config/agent_operator.go
 delete mode 100644 config_server/service/manager/config/config_manager.go
 delete mode 100644 config_server/service/manager/config/user_operator.go
 delete mode 100644 config_server/service/manager/manager.go
 delete mode 100644 config_server/service/model/agent.go
 delete mode 100644 config_server/service/model/agent_group.go
 delete mode 100644 config_server/service/model/collection_config.go
 delete mode 100644 config_server/service/model/model_type.go
 delete mode 100644 config_server/service/proto/agent.pb.go
 delete mode 100644 config_server/service/router/router.go
 delete mode 100644 config_server/service/service.go
 delete mode 100644 config_server/service/setting/mysql-setting.json
 delete mode 100644 config_server/service/setting/setting.go
 delete mode 100644 config_server/service/setting/setting.json
 delete mode 100644 config_server/service/setting/sqlite-setting.json
 delete mode 100644 config_server/service/store/gorm/gorm.go
 delete mode 100644 config_server/service/store/interface_database/interface_database.go
 delete mode 100644 config_server/service/store/leveldb/leveldb.go
 delete mode 100644 config_server/service/store/store.go
 delete mode 100644 config_server/service/test/interface_test.go
 delete mode 100644 config_server/service/test/request.go
 delete mode 100644 config_server/service/test/setting/setting.json
 delete mode 100644 config_server/service/test/setting_test.go
 delete mode 100644 config_server/service/test/store_test.go

diff --git a/config_server/service/.gitignore b/config_server/service/.gitignore
index be5da45682..eb9157e35b 100644
--- a/config_server/service/.gitignore
+++ b/config_server/service/.gitignore
@@ -1,4 +1,4 @@
-DB
+internal/router/cmd
 ConfigServer
-license.sh
-config-server
+cmd/config/dev/*
+.idea
diff --git a/config_server/service/Dockerfile b/config_server/service/Dockerfile
index b75ef08846..e2b10fcfe1 100644
--- a/config_server/service/Dockerfile
+++ b/config_server/service/Dockerfile
@@ -1,39 +1,25 @@
-# Copyright 2023 iLogtail Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
 FROM sls-opensource-registry.cn-shanghai.cr.aliyuncs.com/ilogtail-community-edition/ilogtail-build-linux:2.0.3 as build
 
 USER root
-WORKDIR /src
+WORKDIR /backend
 COPY . .
-RUN go env -w GOPROXY="https://goproxy.cn,direct" && \
-    go build -o ConfigServer
 
-FROM centos:centos7.9.2009
-MAINTAINER TomYu yyuuttaaoo@gmail.com
+RUN go env -w GOPROXY="https://goproxy.cn,direct" \
+    && go mod tidy \
+    && go build -o ConfigServer ./cmd
 
-ENV container docker
 
+FROM centos:centos7.9.2009
 RUN curl -L -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
 
 RUN yum update -y && yum upgrade -y && yum -y clean all && rm -fr /var/cache && rm -rf /core.*
 
-WORKDIR /config_server
-COPY --from=build /src/ConfigServer /config_server/ConfigServer
-COPY --from=build /src/setting/setting.json /config_server/setting/setting.json
-RUN chmod 755 /config_server/ConfigServer && \
-    sed -i 's/127\.0\.0\.1/0\.0\.0\.0/' setting/setting.json
+WORKDIR /backend
+COPY --from=build /backend/cmd /backend/cmd
+COPY --from=build /backend/ConfigServer /backend/ConfigServer
 ENV GIN_MODE=release
 
-CMD ["./ConfigServer"]
+CMD sh -c "./ConfigServer"
+
+
+
diff --git a/config_server/service/Dockerfile-dev b/config_server/service/Dockerfile-dev
new file mode 100644
index 0000000000..38d40eeab5
--- /dev/null
+++ b/config_server/service/Dockerfile-dev
@@ -0,0 +1,13 @@
+FROM sls-opensource-registry.cn-shanghai.cr.aliyuncs.com/ilogtail-community-edition/ilogtail-build-linux:2.0.3 as build
+
+USER root
+WORKDIR /backend
+
+COPY . .
+
+RUN go env -w GOPROXY="https://goproxy.cn,direct" \
+    && go mod tidy
+
+CMD sh -c "go build -o ConfigServer ./cmd && ./ConfigServer"
+
+
diff --git a/config_server/service/README.md b/config_server/service/README.md
new file mode 100644
index 0000000000..7538f1578d
--- /dev/null
+++ b/config_server/service/README.md
@@ -0,0 +1,69 @@
+# Config-server
+
+本项目针对https://github.com/alibaba/ilogtail/tree/main/config_server/protocol/v2 中提到的Agent行为进行了V2版本的适配,基本实现了能力报告、心跳压缩、配置状态上报等功能;并适配用户端实现了Config-server的前端页面Config-server-ui,项目见[ui](../ui/README.md)。
+## 快速开始
+### 基本配置
+下载ilogtail源码,进入`config_server/service`目录
+#### 数据库配置
+
+由于要求ConfigServer存储Agent的基本信息、PipelineConfig、InstanceConfig等配置信息,所以首先需要对数据库进行配置。打开`cmd/config/prod`文件夹,编辑`databaseConfig.json`(若不存在,请先创建),填入以下信息,其中`type`为数据库的基本类型 (基于gorm我们适配了`mysql`、`sqlite`、`postgres`、`sqlserver`四种数据库);其余均为数据库配置信息;`autoMigrate`字段默认为`true`,若先前建好业务相关的表,则设置为`false`。配置完成后,请自行创建可与ConfigServer连通的数据库实例,并创建名字为`dbName`的数据库(若按照docker compose方式启动,无需任何操作,参考[deployment](../deployment/README.md))。
+```json
+{
+  "type": "mysql",
+  "userName": "root",
+  "password": "123456",
+  "host": "mysql",
+  "port": 3306,
+  "dbName": "test",
+  "autoMigrate": true
+}
+```
+
+#### ConfigServer配置
+
+打开`cmd/config/prod`文件夹,编辑`serverConfig.json`(若不存在,请先创建),填入以下信息,其中`address`为应用程序运行的ip和端口;`capabilities`标识Server端拥有的能力,`responseFlags`支持两种配置采集方式,详情见[protocol](https://github.com/alibaba/ilogtail/blob/main/config_server/protocol/v2/README.md);若长时间没接收到某个Agent的心跳检测(超时上限为`timeLimit`,单位是秒),server端自动下线该Agent。
+```json
+{
+  "address": "0.0.0.0:9090",
+  "capabilities": {
+    "rememberAttribute": true,
+    "rememberPipelineConfigStatus": true,
+    "rememberInstanceConfigStatus": true,
+    "rememberCustomCommandStatus": false
+  },
+  "responseFlags": {
+    "fetchPipelineConfigDetail": true,
+    "fetchInstanceConfigDetail": false
+  },
+  "timeLimit":60
+}
+```
+### 运行
+
+按照**基本配置**进行数据库与ConfigServer的配置,进入根目录,运行下面的命令
+
+```shell
+go build -o ConfigServer ./cmd
+
+./ConfigServer
+```
+本项目同样支持docker方式启动应用,Dockerfile见`Dockerfile`(不建议使用,通过docker compose一键部署脚本,可以更快实现应用搭建,参考[deployment](../deployment/README.md))。
+### 启动Agent
+
+Agent 侧需要配置 ConfigServer 信息,才能使用管控功能。从[releases](https://github.com/alibaba/ilogtail/releases) 下载latest版本,配置`ilogtail_config.json`(若不存在,请先创建),添加如下信息,其中`endpoint_list`为ConfigServer的集群地址,并启动Agent。
+```json
+{
+    "config_server_list": [
+        {
+            "cluster": "community",
+            "endpoint_list": [
+                "127.0.0.1:9090"
+            ]
+        }
+    ]
+}
+```
+若Agent以docker方式启动(安装与启动见[start-with-container](https://github.com/alibaba/ilogtail/blob/main/docs/cn/installation/start-with-container.md)),务必保证Agent与ConfigServer的网络连通,可选择以下两种配置方案:
+* 启动时配置Agent与ConfigServer在同一docker网络`server`中,此时`endpoint_list:["config-server:9090"]`。
+* 启动时配置`docker.internal.host`映射,此时`endpoint_list:["docker.internal.host:9090"]`。
+
diff --git a/config_server/service/cmd/config/prod/databaseConfig.json b/config_server/service/cmd/config/prod/databaseConfig.json
new file mode 100644
index 0000000000..1511e146f1
--- /dev/null
+++ b/config_server/service/cmd/config/prod/databaseConfig.json
@@ -0,0 +1,9 @@
+{
+  "type": "mysql",
+  "userName": "root",
+  "password": "123456",
+  "host": "mysql",
+  "port": 3306,
+  "dbName": "test",
+  "autoMigrate": true
+}
\ No newline at end of file
diff --git a/config_server/service/cmd/config/prod/serverConfig.json b/config_server/service/cmd/config/prod/serverConfig.json
new file mode 100644
index 0000000000..e9cf7256c5
--- /dev/null
+++ b/config_server/service/cmd/config/prod/serverConfig.json
@@ -0,0 +1,14 @@
+{
+  "address": "0.0.0.0:9090",
+  "capabilities": {
+    "rememberAttribute": true,
+    "rememberPipelineConfigStatus": true,
+    "rememberInstanceConfigStatus": true,
+    "rememberCustomCommandStatus": false
+  },
+  "responseFlags": {
+    "fetchPipelineConfigDetail": true,
+    "fetchInstanceConfigDetail": false
+  },
+  "timeLimit": 60
+}
\ No newline at end of file
diff --git a/config_server/service/cmd/env.json b/config_server/service/cmd/env.json
new file mode 100644
index 0000000000..866050d02b
--- /dev/null
+++ b/config_server/service/cmd/env.json
@@ -0,0 +1,3 @@
+{
+  "env": "prod"
+}
\ No newline at end of file
diff --git a/config_server/service/cmd/main.go b/config_server/service/cmd/main.go
new file mode 100644
index 0000000000..7a82ea6893
--- /dev/null
+++ b/config_server/service/cmd/main.go
@@ -0,0 +1,16 @@
+package main
+
+import (
+	"config-server/internal/config"
+	"config-server/internal/router"
+	"github.com/gin-gonic/gin"
+)
+
+func main() {
+	r := gin.Default()
+	router.InitAllRouter(r)
+	err := r.Run(config.ServerConfigInstance.Address)
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/config_server/service/common/data_type.go b/config_server/service/common/data_type.go
deleted file mode 100644
index 214e4a9c07..0000000000
--- a/config_server/service/common/data_type.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package common
-
-const (
-	TypeAgentAttributes string = "AGENT_ATTRIBUTES"
-	TypeAgent           string = "AGENT"
-	TypeConfigDetail    string = "CONFIG_DETAIL"
-	TypeAgentGROUP      string = "AGENTGROUP"
-	TypeCommand         string = "COMMAND"
-)
diff --git a/config_server/service/common/http_response.go b/config_server/service/common/http_response.go
deleted file mode 100644
index 3b1b597afd..0000000000
--- a/config_server/service/common/http_response.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package common
-
-type httpStatus struct {
-	Status int
-	Code   string
-}
-
-var (
-	Accept                 = httpStatus{200, "Accept"}
-	BadRequest             = httpStatus{400, "BadRequest"}
-	ConfigAlreadyExist     = httpStatus{400, "ConfigAlreadyExist"}
-	ConfigNotExist         = httpStatus{404, "ConfigNotExist"}
-	InternalServerError    = httpStatus{500, "InternalServerError"}
-	InvalidParameter       = httpStatus{400, "InvalidParameter"}
-	AgentAlreadyExist      = httpStatus{400, "AgentAlreadyExist"}
-	AgentGroupAlreadyExist = httpStatus{400, "AgentGroupAlreadyExist"}
-	AgentGroupNotExist     = httpStatus{404, "AgentGroupNotExist"}
-	AgentNotExist          = httpStatus{404, "AgentNotExist"}
-	RequestTimeout         = httpStatus{500, "RequestTimeout"}
-	ServerBusy             = httpStatus{503, "ServerBusy"}
-)
diff --git a/config_server/service/common/json_file.go b/config_server/service/common/json_file.go
deleted file mode 100644
index 38bd87e136..0000000000
--- a/config_server/service/common/json_file.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package common
-
-import (
-	"encoding/json"
-	"log"
-	"os"
-	"path/filepath"
-)
-
-func ReadJSON(path string, ptr interface{}) error {
-	file, openErr := os.Open(filepath.Clean(path))
-	if openErr != nil {
-		return openErr
-	}
-	defer func() {
-		if closeErr := file.Close(); closeErr != nil {
-			log.Println("Error closing file: " + closeErr.Error())
-		}
-	}()
-
-	decoder := json.NewDecoder(file)
-	decoderErr := decoder.Decode(&ptr)
-	if decoderErr != nil {
-		return decoderErr
-	}
-	return nil
-}
-
-func WriteJSON(path string, data interface{}) error {
-	dataString, marshalErr := json.Marshal(data)
-	if marshalErr != nil {
-		return marshalErr
-	}
-
-	file, openErr := os.OpenFile(filepath.Clean(path), os.O_RDWR|os.O_TRUNC, os.ModeAppend)
-	if openErr != nil {
-		return openErr
-	}
-
-	_, writeErr := file.WriteString(string(dataString))
-	if writeErr != nil {
-		return writeErr
-	}
-	defer func() {
-		if closeErr := file.Close(); closeErr != nil {
-			log.Println("Error closing file: " + closeErr.Error())
-		}
-	}()
-	return nil
-}
diff --git a/config_server/service/common/queue.go b/config_server/service/common/queue.go
deleted file mode 100644
index 93cd1a9b02..0000000000
--- a/config_server/service/common/queue.go
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use q file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package common
-
-type (
-	Queue struct {
-		top    *node
-		rear   *node
-		length int
-	}
-
-	node struct {
-		pre   *node
-		next  *node
-		value interface{}
-	}
-)
-
-// Create a new queue
-func NewQueue() *Queue {
-	return &Queue{nil, nil, 0}
-}
-
-func (q *Queue) Len() int {
-	return q.length
-}
-
-func (q *Queue) Empty() bool {
-	return q.length == 0
-}
-
-func (q *Queue) Front() interface{} {
-	if q.top == nil {
-		return nil
-	}
-	return q.top.value
-}
-
-func (q *Queue) Push(v interface{}) {
-	n := &node{nil, nil, v}
-	if q.length == 0 {
-		q.top = n
-		q.rear = q.top
-	} else {
-		n.pre = q.rear
-		q.rear.next = n
-		q.rear = n
-	}
-	q.length++
-}
-
-func (q *Queue) Pop() interface{} {
-	if q.length == 0 {
-		return nil
-	}
-	n := q.top
-	if q.top.next == nil {
-		q.top = nil
-	} else {
-		q.top = q.top.next
-		q.top.pre.next = nil
-		q.top.pre = nil
-	}
-	q.length--
-	return n.value
-}
-
-func (q *Queue) Clear() {
-	for !q.Empty() {
-		q.Pop()
-	}
-}
diff --git a/config_server/service/example/setting.json b/config_server/service/example/setting.json
deleted file mode 100644
index 27de7cf291..0000000000
--- a/config_server/service/example/setting.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-    "ip":"127.0.0.1",
-    "store_mode": "leveldb",
-    "port": "8899",
-    "db_path": "./DB",
-    "agent_message_update_interval": 1,
-    "collection_config_sync_interval": 3
-}
\ No newline at end of file
diff --git a/config_server/service/go.mod b/config_server/service/go.mod
index 001b8f5fd0..6f14b84fc4 100644
--- a/config_server/service/go.mod
+++ b/config_server/service/go.mod
@@ -3,51 +3,53 @@ module config-server
 go 1.19
 
 require (
-	github.com/gin-gonic/gin v1.8.1
-	github.com/syndtr/goleveldb v1.0.0
-	google.golang.org/protobuf v1.28.0
-	gorm.io/driver/mysql v1.5.4
-	gorm.io/driver/postgres v1.5.7
-	gorm.io/driver/sqlite v1.5.5
+	github.com/gin-gonic/gin v1.10.0
+	google.golang.org/protobuf v1.34.2
+	gorm.io/driver/mysql v1.5.7
+	gorm.io/driver/postgres v1.5.9
+	gorm.io/driver/sqlite v1.5.6
 	gorm.io/driver/sqlserver v1.5.3
-	gorm.io/gorm v1.25.7
+	gorm.io/gorm v1.25.11
 )
 
 require (
+	github.com/bytedance/sonic v1.11.6 // indirect
+	github.com/bytedance/sonic/loader v0.1.1 // indirect
+	github.com/cloudwego/base64x v0.1.4 // indirect
+	github.com/cloudwego/iasm v0.2.0 // indirect
+	github.com/gabriel-vasile/mimetype v1.4.3 // indirect
+	github.com/gin-contrib/sse v0.1.0 // indirect
+	github.com/go-playground/locales v0.14.1 // indirect
+	github.com/go-playground/universal-translator v0.18.1 // indirect
+	github.com/go-playground/validator/v10 v10.20.0 // indirect
 	github.com/go-sql-driver/mysql v1.7.0 // indirect
+	github.com/goccy/go-json v0.10.2 // indirect
 	github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
 	github.com/golang-sql/sqlexp v0.1.0 // indirect
-	github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
 	github.com/jackc/pgpassfile v1.0.0 // indirect
 	github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
-	github.com/jackc/pgx/v5 v5.4.3 // indirect
+	github.com/jackc/pgx/v5 v5.5.5 // indirect
+	github.com/jackc/puddle/v2 v2.2.1 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
-	github.com/jtolds/gls v4.20.0+incompatible // indirect
-	github.com/mattn/go-sqlite3 v1.14.17 // indirect
-	github.com/microsoft/go-mssqldb v1.6.0 // indirect
-	github.com/smartystreets/assertions v1.2.0 // indirect
-)
-
-require (
-	github.com/gin-contrib/sse v0.1.0 // indirect
-	github.com/go-playground/locales v0.14.0 // indirect
-	github.com/go-playground/universal-translator v0.18.0 // indirect
-	github.com/go-playground/validator/v10 v10.10.0 // indirect
-	github.com/goccy/go-json v0.9.7 // indirect
-	github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
-	github.com/leodido/go-urn v1.2.1 // indirect
-	github.com/mattn/go-isatty v0.0.14 // indirect
-	github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
+	github.com/klauspost/cpuid/v2 v2.2.7 // indirect
+	github.com/kr/text v0.2.0 // indirect
+	github.com/leodido/go-urn v1.4.0 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/mattn/go-sqlite3 v1.14.22 // indirect
+	github.com/microsoft/go-mssqldb v1.6.0 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
-	github.com/pelletier/go-toml/v2 v2.0.1 // indirect
-	github.com/smartystreets/goconvey v1.7.2
-	github.com/ugorji/go/codec v1.2.7 // indirect
-	golang.org/x/crypto v0.14.0 // indirect
-	golang.org/x/net v0.14.0 // indirect
-	golang.org/x/sys v0.13.0 // indirect
-	golang.org/x/text v0.13.0 // indirect
-	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
+	github.com/pelletier/go-toml/v2 v2.2.2 // indirect
+	github.com/rogpeppe/go-internal v1.12.0 // indirect
+	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
+	github.com/ugorji/go/codec v1.2.12 // indirect
+	golang.org/x/arch v0.8.0 // indirect
+	golang.org/x/crypto v0.23.0 // indirect
+	golang.org/x/net v0.25.0 // indirect
+	golang.org/x/sync v0.1.0 // indirect
+	golang.org/x/sys v0.20.0 // indirect
+	golang.org/x/text v0.15.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/config_server/service/go.sum b/config_server/service/go.sum
index f3b80eaa71..b1673ae883 100644
--- a/config_server/service/go.sum
+++ b/config_server/service/go.sum
@@ -16,29 +16,37 @@ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0/go.mod h
 github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o=
 github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpCKs6LGGLAhwBARt9632unrVcI6i8s/8os=
 github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
+github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
+github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
+github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
+github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
+github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
+github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
+github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
+github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
 github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
-github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
+github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
 github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
 github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
-github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
-github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
-github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
-github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
-github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
-github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
-github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
-github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
-github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
-github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
+github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
+github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
+github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
 github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
 github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
-github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
-github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
+github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
 github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
 github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
@@ -47,29 +55,22 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0kt
 github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
 github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
 github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
-github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
 github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
 github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
-github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
 github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
 github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
 github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
-github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY=
-github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
+github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
+github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
+github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
+github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
 github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
 github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
 github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
@@ -82,84 +83,71 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
 github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
-github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
-github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
+github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
+github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
 github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
-github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
-github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
-github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
-github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
-github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
-github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
-github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
+github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
+github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
+github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc=
 github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU=
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
 github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
-github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
-github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
-github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
-github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
+github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
+github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
 github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
 github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
-github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
-github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
-github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
-github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
-github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
-github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
-github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
+github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
+github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
 github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
-github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
-github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
-github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
-github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
+github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
+github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
+github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
+golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
 golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
 golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
 golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
-golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
-golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -170,29 +158,27 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
 golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
-golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -201,52 +187,41 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
-google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
+google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
-gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gorm.io/driver/mysql v1.5.4 h1:igQmHfKcbaTVyAIHNhhB888vvxh8EdQ2uSUT0LPcBso=
-gorm.io/driver/mysql v1.5.4/go.mod h1:9rYxJph/u9SWkWc9yY4XJ1F/+xO0S/ChOmbk3+Z5Tvs=
-gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
-gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
-gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E=
-gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE=
+gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
+gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
+gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8=
+gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
+gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE=
+gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
 gorm.io/driver/sqlserver v1.5.3 h1:rjupPS4PVw+rjJkfvr8jn2lJ8BMhT4UW5FwuJY0P3Z0=
 gorm.io/driver/sqlserver v1.5.3/go.mod h1:B+CZ0/7oFJ6tAlefsKoyxdgDCXJKSgwS2bMOQZT0I00=
 gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
-gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A=
 gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
+gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg=
+gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
+nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/config_server/service/interface/agent/collection_config.go b/config_server/service/interface/agent/collection_config.go
deleted file mode 100644
index 1bf463baa1..0000000000
--- a/config_server/service/interface/agent/collection_config.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package agent
-
-import (
-	"github.com/gin-gonic/gin"
-	"github.com/gin-gonic/gin/binding"
-
-	"config-server/common"
-	"config-server/manager"
-	proto "config-server/proto"
-)
-
-func FetchPipelineConfig(c *gin.Context) {
-	req := proto.FetchPipelineConfigRequest{}
-	res := &proto.FetchPipelineConfigResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.RequestId = req.RequestId
-
-	if req.ReqConfigs == nil {
-		req.ReqConfigs = []*proto.ConfigInfo{}
-	}
-
-	c.ProtoBuf(manager.ConfigManager().FetchPipelineConfig(&req, res))
-}
-
-func FetchAgentConfig(c *gin.Context) {
-	req := proto.FetchAgentConfigRequest{}
-	res := &proto.FetchAgentConfigResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.RequestId = req.RequestId
-
-	if req.ReqConfigs == nil {
-		req.ReqConfigs = []*proto.ConfigInfo{}
-	}
-
-	c.ProtoBuf(manager.ConfigManager().FetchAgentConfig(&req, res))
-}
diff --git a/config_server/service/interface/agent/status.go b/config_server/service/interface/agent/status.go
deleted file mode 100644
index 6a970271d8..0000000000
--- a/config_server/service/interface/agent/status.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package agent
-
-import (
-	"fmt"
-
-	"github.com/gin-gonic/gin"
-	"github.com/gin-gonic/gin/binding"
-
-	"config-server/common"
-	"config-server/manager"
-	proto "config-server/proto"
-)
-
-func HeartBeat(c *gin.Context) {
-	req := proto.HeartBeatRequest{}
-	res := &proto.HeartBeatResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.RequestId = req.RequestId
-
-	if req.AgentId == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "AgentID")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	_, res = manager.AgentManager().HeartBeat(&req, res)
-	if res.Code != proto.RespCode_ACCEPT {
-		c.ProtoBuf(common.BadRequest.Status, res)
-	}
-	c.ProtoBuf(manager.ConfigManager().CheckConfigUpdatesWhenHeartbeat(&req, res))
-}
diff --git a/config_server/service/interface/user/agent_group.go b/config_server/service/interface/user/agent_group.go
deleted file mode 100644
index 3b9a4ab3e7..0000000000
--- a/config_server/service/interface/user/agent_group.go
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package user
-
-import (
-	"fmt"
-
-	"github.com/gin-gonic/gin"
-	"github.com/gin-gonic/gin/binding"
-
-	"config-server/common"
-	"config-server/manager"
-	proto "config-server/proto"
-)
-
-func CreateAgentGroup(c *gin.Context) {
-	req := proto.CreateAgentGroupRequest{}
-	res := &proto.CreateAgentGroupResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.AgentGroup.GroupName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group need parameter %s.", "GroupName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().CreateAgentGroup(&req, res))
-}
-
-func UpdateAgentGroup(c *gin.Context) {
-	req := proto.UpdateAgentGroupRequest{}
-	res := &proto.UpdateAgentGroupResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.AgentGroup.GroupName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group need parameter %s.", "groupName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().UpdateAgentGroup(&req, res))
-}
-
-func DeleteAgentGroup(c *gin.Context) {
-	req := proto.DeleteAgentGroupRequest{}
-	res := &proto.DeleteAgentGroupResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.GroupName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group need parameter %s.", "groupName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().DeleteAgentGroup(&req, res))
-}
-
-func GetAgentGroup(c *gin.Context) {
-	req := proto.GetAgentGroupRequest{}
-	res := &proto.GetAgentGroupResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.GroupName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group need parameter %s.", "groupName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().GetAgentGroup(&req, res))
-}
-
-func ListAgentGroups(c *gin.Context) {
-	req := proto.ListAgentGroupsRequest{}
-	res := &proto.ListAgentGroupsResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	c.ProtoBuf(manager.ConfigManager().ListAgentGroups(&req, res))
-}
-
-func ListAgents(c *gin.Context) {
-	req := proto.ListAgentsRequest{}
-	res := &proto.ListAgentsResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.GroupName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "groupName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().ListAgents(&req, res))
-}
-
-func GetAppliedConfigsForAgentGroup(c *gin.Context) {
-	req := proto.GetAppliedConfigsForAgentGroupRequest{}
-	res := &proto.GetAppliedConfigsForAgentGroupResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.GroupName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "GroupName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().GetAppliedConfigsForAgentGroup(&req, res))
-}
-
-func ApplyConfigToAgentGroup(c *gin.Context) {
-	req := proto.ApplyConfigToAgentGroupRequest{}
-	res := &proto.ApplyConfigToAgentGroupResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.GroupName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "groupName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	if req.ConfigName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "configName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().ApplyConfigToAgentGroup(&req, res))
-}
-
-func RemoveConfigFromAgentGroup(c *gin.Context) {
-	req := proto.RemoveConfigFromAgentGroupRequest{}
-	res := &proto.RemoveConfigFromAgentGroupResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.GroupName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "groupName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	if req.ConfigName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "configName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().RemoveConfigFromAgentGroup(&req, res))
-}
diff --git a/config_server/service/interface/user/collection_config.go b/config_server/service/interface/user/collection_config.go
deleted file mode 100644
index 589b4ebfc8..0000000000
--- a/config_server/service/interface/user/collection_config.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package user
-
-import (
-	"fmt"
-
-	"github.com/gin-gonic/gin"
-	"github.com/gin-gonic/gin/binding"
-
-	"config-server/common"
-	"config-server/manager"
-	proto "config-server/proto"
-)
-
-func CreateConfig(c *gin.Context) {
-	req := proto.CreateConfigRequest{}
-	res := &proto.CreateConfigResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.ConfigDetail.Name == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "ConfigName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	if req.ConfigDetail.Detail == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "Detail")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().CreateConfig(&req, res))
-}
-
-func UpdateConfig(c *gin.Context) {
-	req := proto.UpdateConfigRequest{}
-	res := &proto.UpdateConfigResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.ConfigDetail.Name == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "ConfigName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	if req.ConfigDetail.Detail == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "Detail")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().UpdateConfig(&req, res))
-}
-
-func DeleteConfig(c *gin.Context) {
-	req := proto.DeleteConfigRequest{}
-	res := &proto.DeleteConfigResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.ConfigName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "ConfigName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().DeleteConfig(&req, res))
-}
-
-func GetConfig(c *gin.Context) {
-	req := proto.GetConfigRequest{}
-	res := &proto.GetConfigResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.ConfigName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "ConfigName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().GetConfig(&req, res))
-}
-
-func ListConfigs(c *gin.Context) {
-	req := proto.ListConfigsRequest{}
-	res := &proto.ListConfigsResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	c.ProtoBuf(manager.ConfigManager().ListConfigs(&req, res))
-}
-
-func GetAppliedAgentGroups(c *gin.Context) {
-	req := proto.GetAppliedAgentGroupsRequest{}
-	res := &proto.GetAppliedAgentGroupsResponse{}
-
-	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
-	if err != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-	res.ResponseId = req.RequestId
-
-	if req.ConfigName == "" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Need parameter %s.", "ConfigName")
-		c.ProtoBuf(common.BadRequest.Status, res)
-		return
-	}
-
-	c.ProtoBuf(manager.ConfigManager().GetAppliedAgentGroups(&req, res))
-}
diff --git a/config_server/service/internal/common/api_error.go b/config_server/service/internal/common/api_error.go
new file mode 100644
index 0000000000..b6b69244e0
--- /dev/null
+++ b/config_server/service/internal/common/api_error.go
@@ -0,0 +1,63 @@
+package common
+
+import (
+	"errors"
+	"fmt"
+)
+
+type ApiError struct {
+	Code    int
+	Message string
+}
+
+func (apiError ApiError) Error() string {
+	return fmt.Sprintf("Code:%d,Messgae:%s", apiError.Code, apiError.Message)
+}
+
+func ErrorWithMsg(code int, msg string) *ApiError {
+	var apiErrorResult = ApiError{
+		Code:    Failed.Code,
+		Message: Failed.Message,
+	}
+	if code != 0 {
+		apiErrorResult.Code = code
+	}
+	if msg != "" {
+		apiErrorResult.Message = msg
+	}
+	PrintLog(apiErrorResult.Code, apiErrorResult.Message, 3)
+	return &apiErrorResult
+}
+
+func ServerErrorWithMsg(msg string, a ...any) *ApiError {
+	if a == nil || len(a) == 0 {
+		return ErrorWithMsg(Failed.Code, msg)
+	}
+	return ErrorWithMsg(Failed.Code, fmt.Sprintf(msg, a...))
+}
+
+func ServerError() *ApiError {
+	return ErrorWithMsg(Failed.Code, Failed.Message)
+}
+
+//这里切记不要返回APIError,否则会出现问题(因为(ApiError)(nil)!=nil)
+
+func SystemError(err error) error {
+	if err == nil {
+		return nil
+	}
+
+	var apiError *ApiError
+	if errors.As(err, &apiError) {
+		return ErrorWithMsg(apiError.Code, apiError.Message)
+	}
+	return ErrorWithMsg(SystemFailed.Code, err.Error())
+}
+
+func ValidateErrorWithMsg(msg string) *ApiError {
+	return ErrorWithMsg(ValidateFailed.Code, msg)
+}
+
+func ValidateError() *ApiError {
+	return ErrorWithMsg(ValidateFailed.Code, ValidateFailed.Message)
+}
diff --git a/config_server/service/internal/common/http_status.go b/config_server/service/internal/common/http_status.go
new file mode 100644
index 0000000000..4226b310e8
--- /dev/null
+++ b/config_server/service/internal/common/http_status.go
@@ -0,0 +1,25 @@
+package common
+
+import (
+	"github.com/gin-gonic/gin"
+)
+
+type HttpStatus struct {
+	Code    int
+	Message string
+}
+
+var (
+	Success        = HttpStatus{Code: 200, Message: "success"}
+	Failed         = HttpStatus{Code: 500, Message: "failed"}
+	SystemFailed   = HttpStatus{Code: 505, Message: "systemFailed"}
+	ValidateFailed = HttpStatus{Code: 404, Message: "parameter is not"}
+)
+
+func ErrorProtobufRes(c *gin.Context, res any, err error) {
+	c.ProtoBuf(Success.Code, res)
+}
+
+func SuccessProtobufRes(c *gin.Context, res any) {
+	c.ProtoBuf(Success.Code, res)
+}
diff --git a/config_server/service/internal/common/log.go b/config_server/service/internal/common/log.go
new file mode 100644
index 0000000000..361779845a
--- /dev/null
+++ b/config_server/service/internal/common/log.go
@@ -0,0 +1,11 @@
+package common
+
+import (
+	"log"
+	"runtime"
+)
+
+func PrintLog(code int, msg string, skip int) {
+	_, file, line, _ := runtime.Caller(skip)
+	log.Printf("[ERROR]: [%s:%d] Code:%d,Message:%s\n", file, line, code, msg)
+}
diff --git a/config_server/service/internal/common/result.go b/config_server/service/internal/common/result.go
new file mode 100644
index 0000000000..009a6dd47d
--- /dev/null
+++ b/config_server/service/internal/common/result.go
@@ -0,0 +1,26 @@
+package common
+
+import (
+	proto "config-server/internal/protov2"
+	"errors"
+)
+
+func GenerateCommonResponse(err error) *proto.CommonResponse {
+	var apiError *ApiError
+	if err == nil {
+		return &proto.CommonResponse{
+			Status:       0,
+			ErrorMessage: nil,
+		}
+	}
+	if errors.As(err, &apiError) {
+		return &proto.CommonResponse{
+			Status:       int32(apiError.Code),
+			ErrorMessage: []byte(apiError.Message),
+		}
+	}
+	return &proto.CommonResponse{
+		Status:       int32(Failed.Code),
+		ErrorMessage: []byte(err.Error()),
+	}
+}
diff --git a/config_server/service/internal/config/gorm.go b/config_server/service/internal/config/gorm.go
new file mode 100644
index 0000000000..a9d308535c
--- /dev/null
+++ b/config_server/service/internal/config/gorm.go
@@ -0,0 +1,92 @@
+package config
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/utils"
+	"fmt"
+	"gorm.io/driver/mysql"
+	"gorm.io/driver/postgres"
+	"gorm.io/driver/sqlite"
+	"gorm.io/driver/sqlserver"
+	"gorm.io/gorm"
+	"path/filepath"
+)
+
+type GormConfig struct {
+	Type        string `json:"type"`
+	UserName    string `json:"userName"`
+	Password    string `json:"password"`
+	Host        string `json:"host"`
+	Port        int32  `json:"port"`
+	DbName      string `json:"dbName"`
+	AutoMigrate bool   `json:"autoMigrate"`
+}
+
+var gormDialectMap = map[string]func(string) gorm.Dialector{
+	"mysql":     mysql.Open,
+	"sqlite":    sqlite.Open,
+	"sqlserver": sqlserver.Open,
+	"postgres":  postgres.Open,
+}
+
+var config = new(GormConfig)
+
+func Connect2Db() (*GormConfig, gorm.Dialector, error) {
+	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/?charset=utf8&parseTime=True&loc=Local",
+		config.UserName,
+		config.Password,
+		config.Host,
+		config.Port)
+	return getConnection(dsn)
+}
+
+func Connect2SpecifiedDb() (*GormConfig, gorm.Dialector, error) {
+	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local",
+		config.UserName,
+		config.Password,
+		config.Host,
+		config.Port,
+		config.DbName)
+	return getConnection(dsn)
+}
+
+func readDatabaseConfig() error {
+	var err error
+	envName, err := utils.GetEnvName()
+	if err != nil {
+		return err
+	}
+	databaseConfigPath, err := filepath.Abs(fmt.Sprintf("cmd/config/%s/databaseConfig.json", envName))
+	if err != nil {
+		return err
+	}
+	err = utils.ReadJson(databaseConfigPath, config)
+	if err != nil {
+		return err
+	}
+	return err
+}
+
+func getConnection(dsn string) (*GormConfig, gorm.Dialector, error) {
+	if dialect, ok := gormDialectMap[config.Type]; ok {
+		gormDialect := dialect(dsn)
+		if gormDialect == nil {
+			return nil, nil, common.ServerErrorWithMsg("connect %s:%s dbName:%s failed",
+				config.Host, config.Port, config.DbName)
+		}
+		return config, dialect(dsn), nil
+	}
+	adapterDatabaseStr := ""
+	for adapterDatabase := range gormDialectMap {
+		adapterDatabaseStr += adapterDatabase
+		adapterDatabaseStr += ","
+	}
+	panic(fmt.Sprintf("no this database type in (%s)", adapterDatabaseStr[:len(adapterDatabaseStr)-1]))
+}
+
+func init() {
+	err := readDatabaseConfig()
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/config_server/service/internal/config/server.go b/config_server/service/internal/config/server.go
new file mode 100644
index 0000000000..a01ab6351e
--- /dev/null
+++ b/config_server/service/internal/config/server.go
@@ -0,0 +1,43 @@
+package config
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/utils"
+	"fmt"
+	"log"
+	"path/filepath"
+)
+
+type ServerConfig struct {
+	Address       string          `json:"address"`
+	Capabilities  map[string]bool `json:"capabilities"`
+	ResponseFlags map[string]bool `json:"responseFlags"`
+	TimeLimit     int64           `json:"timeLimit"`
+}
+
+var ServerConfigInstance = new(ServerConfig)
+
+func GetServerConfiguration() error {
+	var err error
+	envName, err := utils.GetEnvName()
+	if err != nil {
+		return err
+	}
+	serverConfigPath, err := filepath.Abs(fmt.Sprintf("cmd/config/%s/serverConfig.json", envName))
+	if err != nil {
+		return common.SystemError(err)
+	}
+	err = utils.ReadJson(serverConfigPath, ServerConfigInstance)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	log.Print("server config init...")
+	return nil
+}
+
+func init() {
+	err := GetServerConfiguration()
+	if err != nil {
+		return
+	}
+}
diff --git a/config_server/service/internal/entity/agent.go b/config_server/service/internal/entity/agent.go
new file mode 100644
index 0000000000..a51adf4158
--- /dev/null
+++ b/config_server/service/internal/entity/agent.go
@@ -0,0 +1,111 @@
+package entity
+
+import (
+	"config-server/internal/protov2"
+	"database/sql/driver"
+	"encoding/json"
+	"fmt"
+)
+
+type AgentAttributes struct {
+	Version  []byte
+	Ip       []byte
+	Hostname []byte
+	Extras   map[string][]byte
+}
+
+func (a *AgentAttributes) Parse2Proto() *protov2.AgentAttributes {
+	protoAgentAttributes := new(protov2.AgentAttributes)
+	protoAgentAttributes.Version = a.Version
+	protoAgentAttributes.Ip = a.Ip
+	protoAgentAttributes.Hostname = a.Hostname
+	protoAgentAttributes.Extras = a.Extras
+	return protoAgentAttributes
+}
+
+func ParseProtoAgentAttributes2AgentAttributes(attributes *protov2.AgentAttributes) *AgentAttributes {
+	agentAttributes := new(AgentAttributes)
+	agentAttributes.Version = attributes.Version
+	agentAttributes.Ip = attributes.Ip
+	agentAttributes.Hostname = attributes.Hostname
+	agentAttributes.Extras = attributes.Extras
+	return agentAttributes
+}
+
+func (a *AgentAttributes) Scan(value any) error {
+	if value == nil {
+		return nil
+	}
+
+	b, ok := value.([]byte)
+	if !ok {
+		return fmt.Errorf("value is not []byte, value: %v", value)
+	}
+
+	return json.Unmarshal(b, a)
+}
+
+func (a *AgentAttributes) Value() (driver.Value, error) {
+	v, err := json.Marshal(a)
+	if err != nil {
+		return nil, err
+	}
+	return v, nil
+}
+
+// Preload should write the name of the structure associated field, not the name of the data table or the name of the associated model structure
+
+type Agent struct {
+	SequenceNum     uint64
+	Capabilities    uint64
+	InstanceId      string `gorm:"primarykey"`
+	AgentType       string
+	Attributes      *AgentAttributes
+	Tags            []*AgentGroup `gorm:"many2many:agent_and_agent_group;foreignKey:InstanceId;joinForeignKey:AgentInstanceId;References:Name;joinReferences:AgentGroupName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+	RunningStatus   string
+	StartupTime     int64
+	PipelineConfigs []*PipelineConfig `gorm:"many2many:agent_pipeline_config;foreignKey:InstanceId;joinForeignKey:AgentInstanceId;References:Name;joinReferences:PipelineConfigName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+	InstanceConfigs []*InstanceConfig `gorm:"many2many:agent_instance_config;foreignKey:InstanceId;joinForeignKey:AgentInstanceId;References:Name;joinReferences:InstanceConfigName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+	//CustomCommands  []*CommandInfo
+	Flags             uint64
+	Opaque            []byte
+	LastHeartBeatTime int64
+}
+
+func (a Agent) Parse2Proto() *protov2.Agent {
+	protoAgent := new(protov2.Agent)
+	protoAgent.Capabilities = a.Capabilities
+	protoAgent.InstanceId = []byte(a.InstanceId)
+	protoAgent.AgentType = a.AgentType
+	protoAgent.Attributes = a.Attributes.Parse2Proto()
+	protoAgent.RunningStatus = a.RunningStatus
+	protoAgent.StartupTime = a.StartupTime
+	return protoAgent
+}
+
+// ParseHeartBeatRequest2BasicAgent transfer agent's basic info
+func ParseHeartBeatRequest2BasicAgent(req *protov2.HeartbeatRequest, lastHeartBeatTime int64) *Agent {
+	agent := new(Agent)
+	agent.SequenceNum = req.SequenceNum
+	agent.Capabilities = req.Capabilities
+	agent.InstanceId = string(req.InstanceId)
+	agent.AgentType = req.AgentType
+
+	if req.Tags != nil {
+		for _, tag := range req.Tags {
+			agent.Tags = append(agent.Tags, ParseProtoAgentGroupTag2AgentGroup(tag))
+		}
+	}
+
+	agent.RunningStatus = req.RunningStatus
+	agent.StartupTime = req.StartupTime
+
+	agent.Flags = req.Flags
+	agent.Opaque = req.Opaque
+	agent.LastHeartBeatTime = lastHeartBeatTime
+	return agent
+}
+
+func (Agent) TableName() string {
+	return agentTable
+}
diff --git a/config_server/service/internal/entity/agent_and_config.go b/config_server/service/internal/entity/agent_and_config.go
new file mode 100644
index 0000000000..46d4a8f5d3
--- /dev/null
+++ b/config_server/service/internal/entity/agent_and_config.go
@@ -0,0 +1,81 @@
+package entity
+
+import (
+	proto "config-server/internal/protov2"
+)
+
+type AgentPipelineConfig struct {
+	AgentInstanceId    string `gorm:"primarykey"`
+	PipelineConfigName string `gorm:"primarykey"`
+	Status             ConfigStatus
+	Message            string
+}
+
+func (apc AgentPipelineConfig) TableName() string {
+	return agentPipelineConfigTable
+}
+
+func ParseProtoConfigInfo2AgentPipelineConfig(instanceId string, c *proto.ConfigInfo) *AgentPipelineConfig {
+	return &AgentPipelineConfig{
+		AgentInstanceId:    instanceId,
+		PipelineConfigName: c.Name,
+		Status:             ConfigStatus(c.Status),
+		Message:            c.Message,
+	}
+}
+
+func (apc AgentPipelineConfig) Equals(obj any) bool {
+	if a1, ok := obj.(AgentPipelineConfig); ok {
+		return apc.AgentInstanceId == a1.AgentInstanceId && apc.PipelineConfigName == a1.PipelineConfigName
+	}
+	if a1, ok := obj.(*AgentPipelineConfig); ok {
+		return apc.AgentInstanceId == a1.AgentInstanceId && apc.PipelineConfigName == a1.PipelineConfigName
+	}
+	return false
+}
+
+func (apc AgentPipelineConfig) Parse2ProtoAgentConfigStatus() *proto.AgentConfigStatus {
+	return &proto.AgentConfigStatus{
+		Name:    apc.PipelineConfigName,
+		Status:  proto.ConfigStatus(apc.Status),
+		Message: apc.Message,
+	}
+}
+
+type AgentInstanceConfig struct {
+	AgentInstanceId    string `gorm:"primarykey"`
+	InstanceConfigName string `gorm:"primarykey"`
+	Status             ConfigStatus
+	Message            string
+}
+
+func (aic AgentInstanceConfig) TableName() string {
+	return agentInstanceConfigTable
+}
+
+func ParseProtoConfigInfo2AgentInstanceConfig(instanceId string, c *proto.ConfigInfo) *AgentInstanceConfig {
+	return &AgentInstanceConfig{
+		AgentInstanceId:    instanceId,
+		InstanceConfigName: c.Name,
+		Status:             ConfigStatus(c.Status),
+		Message:            c.Message,
+	}
+}
+
+func (aic AgentInstanceConfig) Parse2ProtoAgentConfigStatus() *proto.AgentConfigStatus {
+	return &proto.AgentConfigStatus{
+		Name:    aic.InstanceConfigName,
+		Status:  proto.ConfigStatus(aic.Status),
+		Message: aic.Message,
+	}
+}
+
+func (aic AgentInstanceConfig) Equals(obj any) bool {
+	if a1, ok := obj.(AgentInstanceConfig); ok {
+		return aic.AgentInstanceId == a1.AgentInstanceId && aic.InstanceConfigName == a1.InstanceConfigName
+	}
+	if a1, ok := obj.(*AgentInstanceConfig); ok {
+		return aic.AgentInstanceId == a1.AgentInstanceId && aic.InstanceConfigName == a1.InstanceConfigName
+	}
+	return false
+}
diff --git a/config_server/service/internal/entity/agent_group.go b/config_server/service/internal/entity/agent_group.go
new file mode 100644
index 0000000000..67a5895218
--- /dev/null
+++ b/config_server/service/internal/entity/agent_group.go
@@ -0,0 +1,33 @@
+package entity
+
+import (
+	proto "config-server/internal/protov2"
+)
+
+const AgentGroupDefaultValue = "default"
+
+type AgentGroup struct {
+	Name            string `gorm:"primarykey;"`
+	Value           string
+	Agents          []*Agent          `gorm:"many2many:agent_and_agent_group;foreignKey:Name;joinForeignKey:AgentGroupName;References:InstanceId;joinReferences:AgentInstanceId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+	PipelineConfigs []*PipelineConfig `gorm:"many2many:agent_group_pipeline_config;foreignKey:Name;joinForeignKey:AgentGroupName;References:Name;joinReferences:PipelineConfigName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+	InstanceConfigs []*InstanceConfig `gorm:"many2many:agent_group_instance_config;foreignKey:Name;joinForeignKey:AgentGroupName;References:Name;joinReferences:InstanceConfigName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+}
+
+func (AgentGroup) TableName() string {
+	return agentGroupTable
+}
+
+func (a AgentGroup) Parse2ProtoAgentGroupTag() *proto.AgentGroupTag {
+	return &proto.AgentGroupTag{
+		Name:  a.Name,
+		Value: a.Value,
+	}
+}
+
+func ParseProtoAgentGroupTag2AgentGroup(tag *proto.AgentGroupTag) *AgentGroup {
+	return &AgentGroup{
+		Name:  tag.Name,
+		Value: tag.Value,
+	}
+}
diff --git a/config_server/service/internal/entity/base.go b/config_server/service/internal/entity/base.go
new file mode 100644
index 0000000000..a11e0983a6
--- /dev/null
+++ b/config_server/service/internal/entity/base.go
@@ -0,0 +1,18 @@
+package entity
+
+const (
+	agentTable               = "agent"
+	agentGroupTable          = "agent_group"
+	pipelineConfigTable      = "pipeline_config"
+	instanceConfigTable      = "instance_config"
+	commandInfoTable         = "command_info"
+	agentPipelineConfigTable = "agent_pipeline_config"
+	agentInstanceConfigTable = "agent_instance_config"
+	//agentAndCommandTable     = "agent_command"
+)
+
+const (
+	AgentAgentGroupTable          = "agent_and_agent_group"
+	AgentGroupPipelineConfigTable = "agent_group_pipeline_config"
+	AgentGroupInstanceConfigTable = "agent_group_instance_config"
+)
diff --git a/config_server/service/internal/entity/command.go b/config_server/service/internal/entity/command.go
new file mode 100644
index 0000000000..8768f39aec
--- /dev/null
+++ b/config_server/service/internal/entity/command.go
@@ -0,0 +1,14 @@
+package entity
+
+type CommandInfo struct {
+	Type       string
+	Name       string       `gorm:"primarykey"`
+	Status     ConfigStatus // Command's status
+	Message    string
+	Detail     []byte
+	ExpireTime int64
+}
+
+func (CommandInfo) TableName() string {
+	return commandInfoTable
+}
diff --git a/config_server/service/internal/entity/config.go b/config_server/service/internal/entity/config.go
new file mode 100644
index 0000000000..b653c257ec
--- /dev/null
+++ b/config_server/service/internal/entity/config.go
@@ -0,0 +1,75 @@
+package entity
+
+import (
+	proto "config-server/internal/protov2"
+)
+
+type ConfigStatus int32
+
+type PipelineConfig struct {
+	Name        string `gorm:"primarykey"`
+	Version     int64
+	Detail      []byte
+	Agents      []*Agent      `gorm:"many2many:agent_pipeline_config;foreignKey:Name;joinForeignKey:PipelineConfigName;References:InstanceId;joinReferences:AgentInstanceId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+	AgentGroups []*AgentGroup `gorm:"many2many:agent_group_pipeline_config;foreignKey:Name;joinForeignKey:PipelineConfigName;References:Name;joinReferences:AgentGroupName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+}
+
+func (PipelineConfig) TableName() string {
+	return pipelineConfigTable
+}
+
+func (c PipelineConfig) Parse2ProtoPipelineConfigDetail(isContainDetail bool) *proto.ConfigDetail {
+	if isContainDetail {
+		return &proto.ConfigDetail{
+			Name:    c.Name,
+			Version: c.Version,
+			Detail:  c.Detail,
+		}
+	}
+	return &proto.ConfigDetail{
+		Name:    c.Name,
+		Version: c.Version,
+	}
+}
+
+func ParseProtoPipelineConfig2PipelineConfig(c *proto.ConfigDetail) *PipelineConfig {
+	return &PipelineConfig{
+		Name:    c.Name,
+		Version: c.Version,
+		Detail:  c.Detail,
+	}
+}
+
+type InstanceConfig struct {
+	Name        string `gorm:"primarykey"`
+	Version     int64
+	Detail      []byte
+	Agents      []*Agent      `gorm:"many2many:agent_instance_config;foreignKey:Name;joinForeignKey:InstanceConfigName;References:InstanceId;joinReferences:AgentInstanceId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+	AgentGroups []*AgentGroup `gorm:"many2many:agent_group_instance_config;foreignKey:Name;joinForeignKey:InstanceConfigName;References:Name;joinReferences:AgentGroupName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+}
+
+func (c InstanceConfig) Parse2ProtoInstanceConfigDetail(isContainDetail bool) *proto.ConfigDetail {
+	if isContainDetail {
+		return &proto.ConfigDetail{
+			Name:    c.Name,
+			Version: c.Version,
+			Detail:  c.Detail,
+		}
+	}
+	return &proto.ConfigDetail{
+		Name:    c.Name,
+		Version: c.Version,
+	}
+}
+
+func ParseProtoInstanceConfig2InstanceConfig(c *proto.ConfigDetail) *InstanceConfig {
+	return &InstanceConfig{
+		Name:    c.Name,
+		Version: c.Version,
+		Detail:  c.Detail,
+	}
+}
+
+func (InstanceConfig) TableName() string {
+	return instanceConfigTable
+}
diff --git a/config_server/service/internal/handler/agent.go b/config_server/service/internal/handler/agent.go
new file mode 100644
index 0000000000..2f90e1c947
--- /dev/null
+++ b/config_server/service/internal/handler/agent.go
@@ -0,0 +1,158 @@
+package handler
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/config"
+	proto "config-server/internal/protov2"
+	"config-server/internal/service"
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+)
+
+func CheckAgentExist() {
+	go service.CheckAgentExist(config.ServerConfigInstance.TimeLimit)
+}
+
+func HeartBeat(c *gin.Context) {
+	request := &proto.HeartbeatRequest{}
+	response := &proto.HeartbeatResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.HeartBeat(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func FetchPipelineConfig(c *gin.Context) {
+	request := &proto.FetchConfigRequest{}
+	response := &proto.FetchConfigResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.FetchPipelineConfigDetail(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func FetchInstanceConfig(c *gin.Context) {
+	request := &proto.FetchConfigRequest{}
+	response := &proto.FetchConfigResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.FetchInstanceConfigDetail(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func ListAgentsInGroup(c *gin.Context) {
+	request := &proto.ListAgentsRequest{}
+	response := &proto.ListAgentsResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.ListAgentsInGroup(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func GetPipelineConfigStatusList(c *gin.Context) {
+	request := &proto.GetConfigStatusListRequest{}
+	response := &proto.GetConfigStatusListResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.GetPipelineConfigStatusList(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func GetInstanceConfigStatusList(c *gin.Context) {
+	request := &proto.GetConfigStatusListRequest{}
+	response := &proto.GetConfigStatusListResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.GetInstanceConfigStatusList(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
diff --git a/config_server/service/internal/handler/agent_group.go b/config_server/service/internal/handler/agent_group.go
new file mode 100644
index 0000000000..f20ea40388
--- /dev/null
+++ b/config_server/service/internal/handler/agent_group.go
@@ -0,0 +1,181 @@
+package handler
+
+import (
+	"config-server/internal/common"
+	proto "config-server/internal/protov2"
+	"config-server/internal/service"
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+)
+
+func AppliedOrRemoveConfigForAgentGroup() {
+	go service.AppliedOrRemoveConfigForAgentGroup(30)
+}
+
+func CreateAgentGroup(c *gin.Context) {
+	request := &proto.CreateAgentGroupRequest{}
+	response := &proto.CreateAgentGroupResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.CreateAgentGroup(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func UpdateAgentGroup(c *gin.Context) {
+	request := &proto.UpdateAgentGroupRequest{}
+	response := &proto.UpdateAgentGroupResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.UpdateAgentGroup(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func DeleteAgentGroup(c *gin.Context) {
+	request := &proto.DeleteAgentGroupRequest{}
+	response := &proto.DeleteAgentGroupResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.DeleteAgentGroup(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func GetAgentGroup(c *gin.Context) {
+	request := &proto.GetAgentGroupRequest{}
+	response := &proto.GetAgentGroupResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.GetAgentGroup(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func ListAgentGroups(c *gin.Context) {
+	request := &proto.ListAgentGroupsRequest{}
+	response := &proto.ListAgentGroupsResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.ListAgentGroups(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func GetAppliedPipelineConfigsForAgentGroup(c *gin.Context) {
+	request := &proto.GetAppliedConfigsForAgentGroupRequest{}
+	response := &proto.GetAppliedConfigsForAgentGroupResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.GetAppliedPipelineConfigsForAgentGroup(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func GetAppliedInstanceConfigsForAgentGroup(c *gin.Context) {
+	request := &proto.GetAppliedConfigsForAgentGroupRequest{}
+	response := &proto.GetAppliedConfigsForAgentGroupResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.GetAppliedInstanceConfigsForAgentGroup(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
diff --git a/config_server/service/internal/handler/instance_config.go b/config_server/service/internal/handler/instance_config.go
new file mode 100644
index 0000000000..4a657bdd10
--- /dev/null
+++ b/config_server/service/internal/handler/instance_config.go
@@ -0,0 +1,201 @@
+package handler
+
+import (
+	"config-server/internal/common"
+	proto "config-server/internal/protov2"
+	"config-server/internal/service"
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+)
+
+func CreateInstanceConfig(c *gin.Context) {
+	request := &proto.CreateConfigRequest{}
+	response := &proto.CreateConfigResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.CreateInstanceConfig(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func UpdateInstanceConfig(c *gin.Context) {
+	request := &proto.UpdateConfigRequest{}
+	response := &proto.UpdateConfigResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.UpdateInstanceConfig(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func DeleteInstanceConfig(c *gin.Context) {
+	request := &proto.DeleteConfigRequest{}
+	response := &proto.DeleteConfigResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.DeleteInstanceConfig(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func GetInstanceConfig(c *gin.Context) {
+	request := &proto.GetConfigRequest{}
+	response := &proto.GetConfigResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.GetInstanceConfig(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func ListInstanceConfigs(c *gin.Context) {
+	request := &proto.ListConfigsRequest{}
+	response := &proto.ListConfigsResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.ListInstanceConfigs(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func ApplyInstanceConfigToAgentGroup(c *gin.Context) {
+	request := &proto.ApplyConfigToAgentGroupRequest{}
+	response := &proto.ApplyConfigToAgentGroupResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.ApplyInstanceConfigToAgentGroup(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func RemoveInstanceConfigFromAgentGroup(c *gin.Context) {
+	request := &proto.RemoveConfigFromAgentGroupRequest{}
+	response := &proto.RemoveConfigFromAgentGroupResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.RemoveInstanceConfigFromAgentGroup(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func GetAppliedAgentGroupsWithInstanceConfig(c *gin.Context) {
+	request := &proto.GetAppliedAgentGroupsRequest{}
+	response := &proto.GetAppliedAgentGroupsResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.GetAppliedAgentGroupsForInstanceConfigName(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
diff --git a/config_server/service/internal/handler/pipeline_config.go b/config_server/service/internal/handler/pipeline_config.go
new file mode 100644
index 0000000000..6311fb101c
--- /dev/null
+++ b/config_server/service/internal/handler/pipeline_config.go
@@ -0,0 +1,203 @@
+package handler
+
+import (
+	"config-server/internal/common"
+	proto "config-server/internal/protov2"
+	"config-server/internal/service"
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+)
+
+func CreatePipelineConfig(c *gin.Context) {
+	request := &proto.CreateConfigRequest{}
+	response := &proto.CreateConfigResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.CreatePipelineConfig(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func UpdatePipelineConfig(c *gin.Context) {
+	request := &proto.UpdateConfigRequest{}
+	response := &proto.UpdateConfigResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.UpdatePipelineConfig(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func DeletePipelineConfig(c *gin.Context) {
+	request := &proto.DeleteConfigRequest{}
+	response := &proto.DeleteConfigResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.DeletePipelineConfig(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func GetPipelineConfig(c *gin.Context) {
+	request := &proto.GetConfigRequest{}
+	response := &proto.GetConfigResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.GetPipelineConfig(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func ListPipelineConfigs(c *gin.Context) {
+	request := &proto.ListConfigsRequest{}
+	response := &proto.ListConfigsResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.ListPipelineConfigs(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+// 对于之前应用到组的配置,若后续有agent加入到组里面,是否需要更新
+
+func ApplyPipelineConfigToAgentGroup(c *gin.Context) {
+	request := &proto.ApplyConfigToAgentGroupRequest{}
+	response := &proto.ApplyConfigToAgentGroupResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.ApplyPipelineConfigToAgentGroup(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func RemovePipelineConfigFromAgentGroup(c *gin.Context) {
+	request := &proto.RemoveConfigFromAgentGroupRequest{}
+	response := &proto.RemoveConfigFromAgentGroupResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.RemovePipelineConfigFromAgentGroup(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
+
+func GetAppliedAgentGroupsWithPipelineConfig(c *gin.Context) {
+	request := &proto.GetAppliedAgentGroupsRequest{}
+	response := &proto.GetAppliedAgentGroupsResponse{}
+	var err error
+	defer func() {
+		response.CommonResponse = common.GenerateCommonResponse(err)
+		common.SuccessProtobufRes(c, response)
+	}()
+	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+	response.RequestId = request.RequestId
+	if response.RequestId == nil {
+		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+	}
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+	err = service.GetAppliedAgentGroupsForPipelineConfigName(request, response)
+	if err != nil {
+		err = common.SystemError(err)
+		return
+	}
+}
diff --git a/config_server/service/internal/manager/agent.go b/config_server/service/internal/manager/agent.go
new file mode 100644
index 0000000000..14065dec3d
--- /dev/null
+++ b/config_server/service/internal/manager/agent.go
@@ -0,0 +1,43 @@
+package manager
+
+import (
+	"config-server/internal/entity"
+	"config-server/internal/repository"
+	"log"
+	"time"
+)
+
+func JudgeSequenceNumRationality(instanceId []byte, sequenceNum uint64) bool {
+	//最开始的心跳检测sequenceNum=0,所以sequenceNum=0是合法的
+	var strInstanceId = string(instanceId)
+	agent := repository.GetAgentByiId(strInstanceId)
+	//找不到数据的时候,同样说明是最开始的状态,应返回true
+	if agent == nil {
+		return true
+	}
+	if sequenceNum != agent.SequenceNum+1 {
+		return false
+	}
+	return true
+}
+
+func CreateOrUpdateAgentBasicInfo(agent *entity.Agent) error {
+	conflictColumnNames := []string{"instance_id"}
+	return repository.CreateOrUpdateAgentBasicInfo(conflictColumnNames, agent)
+}
+
+func GetAllAgentsBasicInfo() []entity.Agent {
+	return repository.GetAllAgents(false, false)
+}
+
+func RemoveAgentNow(agentInfo *entity.Agent, timeLimitNano int64) {
+	nowTime := time.Now().UnixNano()
+	if nowTime-agentInfo.LastHeartBeatTime >= timeLimitNano {
+		err := repository.RemoveAgentById(agentInfo.InstanceId)
+		if err != nil {
+			log.Printf("remove agent (id=%s) error %s", agentInfo.InstanceId, err)
+		} else {
+			log.Printf("remove agent (id=%s) success", agentInfo.InstanceId)
+		}
+	}
+}
diff --git a/config_server/service/internal/manager/agent_group.go b/config_server/service/internal/manager/agent_group.go
new file mode 100644
index 0000000000..01f7af544b
--- /dev/null
+++ b/config_server/service/internal/manager/agent_group.go
@@ -0,0 +1,87 @@
+package manager
+
+import (
+	"config-server/internal/entity"
+	"config-server/internal/repository"
+	"config-server/internal/utils"
+)
+
+func AddDefaultAgentGroup(agentTags []*entity.AgentGroup) []*entity.AgentGroup {
+	if agentTags == nil || len(agentTags) == 0 {
+		agentTags = append(agentTags, &entity.AgentGroup{
+			Name:  entity.AgentGroupDefaultValue,
+			Value: entity.AgentGroupDefaultValue,
+		})
+	}
+	return agentTags
+}
+
+func AppliedOrRemovePipelineConfigForAgentGroup(agentGroupDetails []*entity.AgentGroup) {
+	agentPipelineConfigList := repository.ListAgentPipelineConfig()
+	processAgentPipelineConfigMapList := make([]*entity.AgentPipelineConfig, 0)
+	for _, agentGroupDetail := range agentGroupDetails {
+		agents := agentGroupDetail.Agents
+
+		pipelineConfigs := agentGroupDetail.PipelineConfigs
+		for _, agent := range agents {
+			for _, pipelineConfig := range pipelineConfigs {
+				a := &entity.AgentPipelineConfig{
+					AgentInstanceId:    agent.InstanceId,
+					PipelineConfigName: pipelineConfig.Name,
+				}
+				//以agentGroup中 group与agent的关系为主
+				if !utils.ContainElement(processAgentPipelineConfigMapList, a, (*entity.AgentPipelineConfig).Equals) {
+					processAgentPipelineConfigMapList = append(processAgentPipelineConfigMapList, a)
+				}
+			}
+		}
+		// 如果agent与config的关系 存在于 agentGroup与config的关系中,则以前者为主
+		for _, agentPipelineConfig := range agentPipelineConfigList {
+			utils.ReplaceElement(processAgentPipelineConfigMapList, agentPipelineConfig, (*entity.AgentPipelineConfig).Equals)
+		}
+
+	}
+	repository.DeleteAllPipelineConfigAndAgent()
+	if processAgentPipelineConfigMapList != nil && len(processAgentPipelineConfigMapList) != 0 {
+		err := CreateOrUpdateAgentPipelineConfigs(processAgentPipelineConfigMapList)
+		if err != nil {
+			panic(err)
+		}
+	}
+}
+
+func AppliedOrRemoveInstanceConfigForAgentGroup(agentGroupDetails []*entity.AgentGroup) {
+	agentInstanceConfigList := repository.ListAgentInstanceConfig()
+	processAgentInstanceConfigMapList := make([]*entity.AgentInstanceConfig, 0)
+	for _, agentGroupDetail := range agentGroupDetails {
+		agents := agentGroupDetail.Agents
+
+		instanceConfigs := agentGroupDetail.InstanceConfigs
+		for _, agent := range agents {
+			for _, instanceConfig := range instanceConfigs {
+				a := &entity.AgentInstanceConfig{
+					AgentInstanceId:    agent.InstanceId,
+					InstanceConfigName: instanceConfig.Name,
+				}
+				//以agentGroup中 group与agent的关系为主
+				if !utils.ContainElement(processAgentInstanceConfigMapList, a, (*entity.AgentInstanceConfig).Equals) {
+					processAgentInstanceConfigMapList = append(processAgentInstanceConfigMapList, a)
+				}
+			}
+		}
+		// 如果agent与config的关系 存在于 agentGroup与config的关系中,则以前者为主
+		for _, agentInstanceConfig := range agentInstanceConfigList {
+			utils.ReplaceElement(processAgentInstanceConfigMapList, agentInstanceConfig, (*entity.AgentInstanceConfig).Equals)
+		}
+
+	}
+
+	repository.DeleteAllInstanceConfigAndAgent()
+	if processAgentInstanceConfigMapList != nil && len(processAgentInstanceConfigMapList) != 0 {
+		err := CreateOrUpdateAgentInstanceConfigs(processAgentInstanceConfigMapList)
+		if err != nil {
+			panic(err)
+		}
+	}
+
+}
diff --git a/config_server/service/internal/manager/capability/agent.go b/config_server/service/internal/manager/capability/agent.go
new file mode 100644
index 0000000000..a51bbb392d
--- /dev/null
+++ b/config_server/service/internal/manager/capability/agent.go
@@ -0,0 +1,88 @@
+package capability
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/manager"
+	proto "config-server/internal/protov2"
+	"log"
+)
+
+type AgentAction struct {
+	Base
+	run func(*proto.HeartbeatRequest, *proto.HeartbeatResponse, ...any) error
+}
+
+func (a AgentAction) Action(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse, arg ...any) error {
+	code := a.Code
+	if int(req.Capabilities)&code == code {
+		err := a.run(req, res, arg...)
+		return common.SystemError(err)
+	}
+	return nil
+}
+
+var (
+	AgentUnSpecifiedAction = &AgentAction{
+		Base: AgentUnSpecified,
+		run:  UnspecifiedRun,
+	}
+	AcceptsPipelineConfigAction = &AgentAction{
+		Base: AcceptsPipelineConfig,
+		run:  AcceptsPipelineConfigRun,
+	}
+	AcceptsInstanceConfigAction = AgentAction{
+		Base: AcceptsInstanceConfig,
+		run:  AcceptsInstanceConfigRun,
+	}
+	AcceptsCustomCommandAction = &AgentAction{
+		Base: AcceptsCustomCommand,
+		run:  AcceptsCustomCommandRun,
+	}
+)
+
+//agent有接收某种配置的能力,则响应中设置对应的配置
+
+func UnspecifiedRun(*proto.HeartbeatRequest, *proto.HeartbeatResponse, ...any) error {
+	return nil
+}
+
+// AcceptsPipelineConfigRun 返回PipelineConfigDetail
+func AcceptsPipelineConfigRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse, arg ...any) error {
+	if arg == nil || len(arg) == 0 {
+		return common.ServerErrorWithMsg("The arg parameter cannot be null")
+	}
+
+	if isContainDetail, ok := arg[0].(bool); ok {
+		strInstanceId := string(req.InstanceId)
+		pipelineConfigUpdates, err := manager.GetPipelineConfigs(strInstanceId, isContainDetail)
+		if err != nil {
+			return common.SystemError(err)
+		}
+		res.PipelineConfigUpdates = pipelineConfigUpdates
+		return nil
+	}
+	return common.ServerErrorWithMsg("Arg is illegal, what is required is a boolean type parameter")
+}
+
+// AcceptsInstanceConfigRun 返回InstanceConfigDetail
+func AcceptsInstanceConfigRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse, arg ...any) error {
+	if arg == nil || len(arg) == 0 {
+		return common.ServerErrorWithMsg("The arg parameter cannot be null")
+	}
+
+	if isContainDetail, ok := arg[0].(bool); ok {
+		strInstanceId := string(req.InstanceId)
+		instanceConfigUpdates, err := manager.GetInstanceConfigs(strInstanceId, isContainDetail)
+		if err != nil {
+			return common.SystemError(err)
+		}
+		res.InstanceConfigUpdates = instanceConfigUpdates
+		return nil
+	}
+	return common.ServerErrorWithMsg("Arg is illegal, what is required is a boolean type parameter")
+}
+
+func AcceptsCustomCommandRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse, arg ...any) error {
+	log.Print("command capability action run ...")
+	return nil
+}
diff --git a/config_server/service/internal/manager/capability/common.go b/config_server/service/internal/manager/capability/common.go
new file mode 100644
index 0000000000..7ec3ff94a2
--- /dev/null
+++ b/config_server/service/internal/manager/capability/common.go
@@ -0,0 +1,23 @@
+package capability
+
+type Base struct {
+	Code  int
+	Value string
+}
+
+// server
+var (
+	ServerUnspecified            = Base{0, "unspecified"}
+	RememberAttribute            = Base{1, "rememberAttribute"}
+	RememberPipelineConfigStatus = Base{2, "rememberPipelineConfigStatus"}
+	RememberInstanceConfigStatus = Base{4, "rememberInstanceConfigStatus"}
+	RememberCustomCommandStatus  = Base{8, "rememberCustomCommandStatus"}
+)
+
+// agent
+var (
+	AgentUnSpecified      = Base{0, "unspecified"}
+	AcceptsPipelineConfig = Base{1, "acceptsPipelineConfig"}
+	AcceptsInstanceConfig = Base{2, "acceptsInstanceConfig"}
+	AcceptsCustomCommand  = Base{4, "acceptsCustomCommand"}
+)
diff --git a/config_server/service/internal/manager/capability/server.go b/config_server/service/internal/manager/capability/server.go
new file mode 100644
index 0000000000..02044bc83a
--- /dev/null
+++ b/config_server/service/internal/manager/capability/server.go
@@ -0,0 +1,112 @@
+package capability
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/config"
+	"config-server/internal/entity"
+	"config-server/internal/manager"
+	proto "config-server/internal/protov2"
+	"config-server/internal/repository"
+)
+
+type ServerAction struct {
+	Base
+	run func(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error
+}
+
+func (a ServerAction) Action(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	serverCapabilityType := a.Value
+	hasServerCapability, ok := config.ServerConfigInstance.Capabilities[serverCapabilityType]
+	if !ok {
+		return common.ServerErrorWithMsg("error serverCapability type(%s)", serverCapabilityType)
+	}
+
+	if hasServerCapability {
+		err := a.run(req, res)
+		return common.SystemError(err)
+	}
+	return nil
+}
+
+func (a ServerAction) UpdateCapabilities(res *proto.HeartbeatResponse) {
+	res.Capabilities = res.Capabilities | uint64(a.Code)
+}
+
+var (
+	UnspecifiedServerAction = &ServerAction{
+		Base: ServerUnspecified,
+		run:  UnspecifiedServerCapabilityRun,
+	}
+
+	RememberAttributeAction = &ServerAction{
+		Base: RememberAttribute,
+		run:  RememberAttributeCapabilityRun,
+	}
+	RememberPipelineConfigStatusAction = &ServerAction{
+		Base: RememberPipelineConfigStatus,
+		run:  RememberPipelineConfigStatusCapabilityRun,
+	}
+	RememberInstanceConfigStatusAction = &ServerAction{
+		Base: RememberInstanceConfigStatus,
+		run:  RememberInstanceConfigStatusCapabilityRun,
+	}
+	RememberCustomCommandStatusAction = &ServerAction{
+		Base: RememberCustomCommandStatus,
+		run:  RememberCustomCommandStatusRun,
+	}
+)
+
+var ServerActionList = []*ServerAction{
+	UnspecifiedServerAction,
+	RememberAttributeAction,
+	RememberPipelineConfigStatusAction,
+	RememberInstanceConfigStatusAction,
+	RememberCustomCommandStatusAction,
+}
+
+func UnspecifiedServerCapabilityRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	return nil
+}
+
+func RememberAttributeCapabilityRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	attributes := req.Attributes
+	if attributes == nil {
+		return nil
+	}
+	agent := &entity.Agent{}
+	agent.Attributes = entity.ParseProtoAgentAttributes2AgentAttributes(attributes)
+	err := repository.UpdateAgentById(agent, "attributes")
+	return common.SystemError(err)
+}
+
+func RememberPipelineConfigStatusCapabilityRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	configs := req.PipelineConfigs
+	if configs == nil {
+		return nil
+	}
+	agentPipelineConfigs := make([]*entity.AgentPipelineConfig, 0)
+	for _, reqPipelineConfig := range req.PipelineConfigs {
+		agentPipelineConfig := entity.ParseProtoConfigInfo2AgentPipelineConfig(string(req.InstanceId), reqPipelineConfig)
+		agentPipelineConfigs = append(agentPipelineConfigs, agentPipelineConfig)
+	}
+	err := manager.CreateOrUpdateAgentPipelineConfigs(agentPipelineConfigs)
+	return common.SystemError(err)
+}
+
+func RememberInstanceConfigStatusCapabilityRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	configs := req.InstanceConfigs
+	if configs == nil {
+		return nil
+	}
+	agentInstanceConfigs := make([]*entity.AgentInstanceConfig, 0)
+	for _, reqInstanceConfig := range req.InstanceConfigs {
+		agentInstanceConfig := entity.ParseProtoConfigInfo2AgentInstanceConfig(string(req.InstanceId), reqInstanceConfig)
+		agentInstanceConfigs = append(agentInstanceConfigs, agentInstanceConfig)
+	}
+	err := manager.CreateOrUpdateAgentInstanceConfigs(agentInstanceConfigs)
+	return common.SystemError(err)
+}
+
+func RememberCustomCommandStatusRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	return nil
+}
diff --git a/config_server/service/internal/manager/config.go b/config_server/service/internal/manager/config.go
new file mode 100644
index 0000000000..c48949fd0b
--- /dev/null
+++ b/config_server/service/internal/manager/config.go
@@ -0,0 +1,54 @@
+package manager
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/entity"
+	proto "config-server/internal/protov2"
+	"config-server/internal/repository"
+)
+
+func CreateOrUpdateAgentInstanceConfigs(agentInstanceConfigs []*entity.AgentInstanceConfig) error {
+	conflictColumnNames := []string{"agent_instance_id", "instance_config_name"}
+	assignmentColumnNames := []string{"status", "message"}
+	err := repository.CreateOrUpdateAgentInstanceConfigs(conflictColumnNames, assignmentColumnNames, agentInstanceConfigs...)
+	return common.SystemError(err)
+}
+
+func CreateOrUpdateAgentPipelineConfigs(agentPipelineConfigs []*entity.AgentPipelineConfig) error {
+	conflictColumnNames := []string{"agent_instance_id", "pipeline_config_name"}
+	assignmentColumnNames := []string{"status", "message"}
+	err := repository.CreateOrUpdateAgentPipelineConfigs(conflictColumnNames, assignmentColumnNames, agentPipelineConfigs...)
+	return common.SystemError(err)
+}
+
+func GetPipelineConfigs(instanceId string, isContainDetail bool) ([]*proto.ConfigDetail, error) {
+	var err error
+	agent := &entity.Agent{InstanceId: instanceId}
+	err = repository.GetPipelineConfigsByAgent(agent)
+	if err != nil {
+		return nil, err
+	}
+
+	pipelineConfigUpdates := make([]*proto.ConfigDetail, 0)
+	for _, config := range agent.PipelineConfigs {
+		detail := config.Parse2ProtoPipelineConfigDetail(isContainDetail)
+		pipelineConfigUpdates = append(pipelineConfigUpdates, detail)
+	}
+	return pipelineConfigUpdates, nil
+}
+
+func GetInstanceConfigs(instanceId string, isContainDetail bool) ([]*proto.ConfigDetail, error) {
+	var err error
+	agent := &entity.Agent{InstanceId: instanceId}
+	err = repository.GetInstanceConfigsByAgent(agent)
+	if err != nil {
+		return nil, err
+	}
+
+	instanceConfigUpdates := make([]*proto.ConfigDetail, 0)
+	for _, config := range agent.InstanceConfigs {
+		detail := config.Parse2ProtoInstanceConfigDetail(isContainDetail)
+		instanceConfigUpdates = append(instanceConfigUpdates, detail)
+	}
+	return instanceConfigUpdates, err
+}
diff --git a/config_server/service/internal/manager/flag/request.go b/config_server/service/internal/manager/flag/request.go
new file mode 100644
index 0000000000..cb674d28f0
--- /dev/null
+++ b/config_server/service/internal/manager/flag/request.go
@@ -0,0 +1,60 @@
+package flag
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/manager/capability"
+	proto "config-server/internal/protov2"
+)
+
+const (
+	RequestUnspecified     = "unspecified"
+	RequestReportFullState = "reportFullState"
+)
+
+type RequestAction struct {
+	Value string
+	Run   func(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error
+}
+
+var RequestMap = map[int]*RequestAction{
+	0: {
+		Value: RequestUnspecified,
+		Run:   RequestUnspecifiedRun,
+	},
+	1: {
+		Value: RequestReportFullState,
+		Run:   RequestReportFullStateRun,
+	},
+}
+
+// RequestUnspecifiedRun agent上报简单信息
+func RequestUnspecifiedRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	for _, action := range capability.ServerActionList {
+		action.UpdateCapabilities(res)
+	}
+	return nil
+}
+
+// RequestReportFullStateRun agent上传全量信息
+func RequestReportFullStateRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	for _, action := range capability.ServerActionList {
+		action.UpdateCapabilities(res)
+		err := action.Action(req, res)
+		if err != nil {
+			return common.SystemError(err)
+		}
+	}
+	return nil
+}
+
+func HandleRequestFlags(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	for key, value := range RequestMap {
+		if int(req.Flags)&key == key {
+			err := value.Run(req, res)
+			if err != nil {
+				return common.SystemError(err)
+			}
+		}
+	}
+	return nil
+}
diff --git a/config_server/service/internal/manager/flag/response.go b/config_server/service/internal/manager/flag/response.go
new file mode 100644
index 0000000000..2b88a7f7ac
--- /dev/null
+++ b/config_server/service/internal/manager/flag/response.go
@@ -0,0 +1,100 @@
+package flag
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/config"
+	"config-server/internal/manager/capability"
+	proto "config-server/internal/protov2"
+)
+
+type ResponseAction struct {
+	Code int
+	Run1 func(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error
+	Run2 func(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error
+}
+
+const (
+	Unspecified               = "unspecified"
+	ReportFullState           = "reportFullState"
+	FetchPipelineConfigDetail = "fetchPipelineConfigDetail"
+	FetchInstanceConfigDetail = "fetchInstanceConfigDetail"
+)
+
+var ResponseMap = map[string]*ResponseAction{
+	Unspecified: {
+		Code: 0,
+		Run1: ResponseUnspecifiedRun,
+	},
+	ReportFullState: {
+		Code: 1,
+		Run1: ResponseReportFullStateRun,
+	},
+	FetchPipelineConfigDetail: {
+		Code: 2,
+		Run1: FetchPipelineConfigDetailRun,
+		Run2: FetchPipelineConfigDetailIncludeDetailRun,
+	},
+	FetchInstanceConfigDetail: {
+		Code: 4,
+		Run1: FetchInstanceConfigDetailRun,
+		Run2: FetchInstanceConfigDetailIncludeDetailRun,
+	},
+}
+
+func ResponseUnspecifiedRun(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error {
+	return nil
+}
+
+func ResponseReportFullStateRun(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error {
+	return nil
+}
+
+func FetchPipelineConfigDetailIncludeDetailRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	err := capability.AcceptsPipelineConfigAction.Action(req, res, true)
+	return common.SystemError(err)
+}
+
+// FetchPipelineConfigDetailRun 要求agent做的事情,比如配置不发送pipelineConfig的Detail,
+// 这里就要求它主动请求FetchPipelineConfig接口(只需改变res.flags并且configUpdate不包含detail)
+func FetchPipelineConfigDetailRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	err := capability.AcceptsPipelineConfigAction.Action(req, res, false)
+	return common.SystemError(err)
+}
+
+func FetchInstanceConfigDetailRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	err := capability.AcceptsInstanceConfigAction.Action(req, res, false)
+	return common.SystemError(err)
+}
+
+func FetchInstanceConfigDetailIncludeDetailRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	err := capability.AcceptsInstanceConfigAction.Action(req, res, true)
+	return common.SystemError(err)
+}
+
+func HandleResponseFlags(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	for key, value := range config.ServerConfigInstance.ResponseFlags {
+		action, ok := ResponseMap[key]
+		if !ok {
+			panic("not the correct responseFlags config...")
+		}
+		if value {
+			res.Flags = res.Flags | uint64(action.Code)
+			if action.Run1 == nil {
+				continue
+			}
+			err := action.Run1(req, res)
+			if err != nil {
+				return common.SystemError(err)
+			}
+		} else {
+			if action.Run2 == nil {
+				continue
+			}
+			err := action.Run2(req, res)
+			if err != nil {
+				return common.SystemError(err)
+			}
+		}
+	}
+	return nil
+}
diff --git a/config_server/service/internal/protov2/agent.pb.go b/config_server/service/internal/protov2/agent.pb.go
new file mode 100644
index 0000000000..aa3e46b51e
--- /dev/null
+++ b/config_server/service/internal/protov2/agent.pb.go
@@ -0,0 +1,1531 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.34.2
+// 	protoc        v3.20.0
+// source: agent.proto
+
+package protov2
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type ConfigStatus int32
+
+const (
+	// The value of status field is not set.
+	ConfigStatus_UNSET ConfigStatus = 0
+	// Agent is currently applying the remote config that it received earlier.
+	ConfigStatus_APPLYING ConfigStatus = 1
+	// Remote config was successfully applied by the Agent.
+	ConfigStatus_APPLIED ConfigStatus = 2
+	// Agent tried to apply the config received earlier, but it failed.
+	// See error_message for more details.
+	ConfigStatus_FAILED ConfigStatus = 3
+)
+
+// Enum value maps for ConfigStatus.
+var (
+	ConfigStatus_name = map[int32]string{
+		0: "UNSET",
+		1: "APPLYING",
+		2: "APPLIED",
+		3: "FAILED",
+	}
+	ConfigStatus_value = map[string]int32{
+		"UNSET":    0,
+		"APPLYING": 1,
+		"APPLIED":  2,
+		"FAILED":   3,
+	}
+)
+
+func (x ConfigStatus) Enum() *ConfigStatus {
+	p := new(ConfigStatus)
+	*p = x
+	return p
+}
+
+func (x ConfigStatus) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ConfigStatus) Descriptor() protoreflect.EnumDescriptor {
+	return file_agent_proto_enumTypes[0].Descriptor()
+}
+
+func (ConfigStatus) Type() protoreflect.EnumType {
+	return &file_agent_proto_enumTypes[0]
+}
+
+func (x ConfigStatus) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ConfigStatus.Descriptor instead.
+func (ConfigStatus) EnumDescriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{0}
+}
+
+type AgentCapabilities int32
+
+const (
+	// The capabilities field is unspecified.
+	AgentCapabilities_UnspecifiedAgentCapability AgentCapabilities = 0
+	// The Agent can accept pipeline configuration from the Server.
+	AgentCapabilities_AcceptsPipelineConfig AgentCapabilities = 1
+	// The Agent can accept instance configuration from the Server.
+	AgentCapabilities_AcceptsInstanceConfig AgentCapabilities = 2
+	// The Agent can accept custom command from the Server.
+	AgentCapabilities_AcceptsCustomCommand AgentCapabilities = 4
+)
+
+// Enum value maps for AgentCapabilities.
+var (
+	AgentCapabilities_name = map[int32]string{
+		0: "UnspecifiedAgentCapability",
+		1: "AcceptsPipelineConfig",
+		2: "AcceptsInstanceConfig",
+		4: "AcceptsCustomCommand",
+	}
+	AgentCapabilities_value = map[string]int32{
+		"UnspecifiedAgentCapability": 0,
+		"AcceptsPipelineConfig":      1,
+		"AcceptsInstanceConfig":      2,
+		"AcceptsCustomCommand":       4,
+	}
+)
+
+func (x AgentCapabilities) Enum() *AgentCapabilities {
+	p := new(AgentCapabilities)
+	*p = x
+	return p
+}
+
+func (x AgentCapabilities) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (AgentCapabilities) Descriptor() protoreflect.EnumDescriptor {
+	return file_agent_proto_enumTypes[1].Descriptor()
+}
+
+func (AgentCapabilities) Type() protoreflect.EnumType {
+	return &file_agent_proto_enumTypes[1]
+}
+
+func (x AgentCapabilities) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use AgentCapabilities.Descriptor instead.
+func (AgentCapabilities) EnumDescriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{1}
+}
+
+type RequestFlags int32
+
+const (
+	RequestFlags_RequestFlagsUnspecified RequestFlags = 0
+	// Must be set if this request contains full state
+	RequestFlags_FullState RequestFlags = 1 // bits before 2^16 (inclusive) are reserved for future official fields
+)
+
+// Enum value maps for RequestFlags.
+var (
+	RequestFlags_name = map[int32]string{
+		0: "RequestFlagsUnspecified",
+		1: "FullState",
+	}
+	RequestFlags_value = map[string]int32{
+		"RequestFlagsUnspecified": 0,
+		"FullState":               1,
+	}
+)
+
+func (x RequestFlags) Enum() *RequestFlags {
+	p := new(RequestFlags)
+	*p = x
+	return p
+}
+
+func (x RequestFlags) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (RequestFlags) Descriptor() protoreflect.EnumDescriptor {
+	return file_agent_proto_enumTypes[2].Descriptor()
+}
+
+func (RequestFlags) Type() protoreflect.EnumType {
+	return &file_agent_proto_enumTypes[2]
+}
+
+func (x RequestFlags) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use RequestFlags.Descriptor instead.
+func (RequestFlags) EnumDescriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{2}
+}
+
+type ServerCapabilities int32
+
+const (
+	// The capabilities field is unspecified.
+	ServerCapabilities_UnspecifiedServerCapability ServerCapabilities = 0
+	// The Server can remember agent attributes.
+	ServerCapabilities_RembersAttribute ServerCapabilities = 1
+	// The Server can remember pipeline config status.
+	ServerCapabilities_RembersPipelineConfigStatus ServerCapabilities = 2
+	// The Server can remember instance config status.
+	ServerCapabilities_RembersInstanceConfigStatus ServerCapabilities = 4
+	// The Server can remember custom command status.
+	ServerCapabilities_RembersCustomCommandStatus ServerCapabilities = 8
+)
+
+// Enum value maps for ServerCapabilities.
+var (
+	ServerCapabilities_name = map[int32]string{
+		0: "UnspecifiedServerCapability",
+		1: "RembersAttribute",
+		2: "RembersPipelineConfigStatus",
+		4: "RembersInstanceConfigStatus",
+		8: "RembersCustomCommandStatus",
+	}
+	ServerCapabilities_value = map[string]int32{
+		"UnspecifiedServerCapability": 0,
+		"RembersAttribute":            1,
+		"RembersPipelineConfigStatus": 2,
+		"RembersInstanceConfigStatus": 4,
+		"RembersCustomCommandStatus":  8,
+	}
+)
+
+func (x ServerCapabilities) Enum() *ServerCapabilities {
+	p := new(ServerCapabilities)
+	*p = x
+	return p
+}
+
+func (x ServerCapabilities) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ServerCapabilities) Descriptor() protoreflect.EnumDescriptor {
+	return file_agent_proto_enumTypes[3].Descriptor()
+}
+
+func (ServerCapabilities) Type() protoreflect.EnumType {
+	return &file_agent_proto_enumTypes[3]
+}
+
+func (x ServerCapabilities) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ServerCapabilities.Descriptor instead.
+func (ServerCapabilities) EnumDescriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{3}
+}
+
+type ResponseFlags int32
+
+const (
+	ResponseFlags_ResponseFlagsUnspecified ResponseFlags = 0
+	// ReportFullState flag can be used by the Server if the Client did not include
+	// some sub-message in the last AgentToServer message (which is an allowed
+	// optimization) but the Server detects that it does not have it (e.g. was
+	// restarted and lost state).
+	ResponseFlags_ReportFullState           ResponseFlags = 1
+	ResponseFlags_FetchPipelineConfigDetail ResponseFlags = 2
+	ResponseFlags_FetchInstanceConfigDetail ResponseFlags = 4 // bits before 2^16 (inclusive) are reserved for future official fields
+)
+
+// Enum value maps for ResponseFlags.
+var (
+	ResponseFlags_name = map[int32]string{
+		0: "ResponseFlagsUnspecified",
+		1: "ReportFullState",
+		2: "FetchPipelineConfigDetail",
+		4: "FetchInstanceConfigDetail",
+	}
+	ResponseFlags_value = map[string]int32{
+		"ResponseFlagsUnspecified":  0,
+		"ReportFullState":           1,
+		"FetchPipelineConfigDetail": 2,
+		"FetchInstanceConfigDetail": 4,
+	}
+)
+
+func (x ResponseFlags) Enum() *ResponseFlags {
+	p := new(ResponseFlags)
+	*p = x
+	return p
+}
+
+func (x ResponseFlags) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ResponseFlags) Descriptor() protoreflect.EnumDescriptor {
+	return file_agent_proto_enumTypes[4].Descriptor()
+}
+
+func (ResponseFlags) Type() protoreflect.EnumType {
+	return &file_agent_proto_enumTypes[4]
+}
+
+func (x ResponseFlags) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ResponseFlags.Descriptor instead.
+func (ResponseFlags) EnumDescriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{4}
+}
+
+type AgentGroupTag struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name  string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (x *AgentGroupTag) Reset() {
+	*x = AgentGroupTag{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AgentGroupTag) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AgentGroupTag) ProtoMessage() {}
+
+func (x *AgentGroupTag) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AgentGroupTag.ProtoReflect.Descriptor instead.
+func (*AgentGroupTag) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *AgentGroupTag) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *AgentGroupTag) GetValue() string {
+	if x != nil {
+		return x.Value
+	}
+	return ""
+}
+
+// Define the Config information carried in the request
+type ConfigInfo struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name    string       `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`                        // Required, Config's unique identification
+	Version int64        `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"`                 // Required, Config's version number or hash code
+	Status  ConfigStatus `protobuf:"varint,3,opt,name=status,proto3,enum=ConfigStatus" json:"status,omitempty"` // Config's status
+	Message string       `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"`                  // Optional error message
+}
+
+func (x *ConfigInfo) Reset() {
+	*x = ConfigInfo{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ConfigInfo) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ConfigInfo) ProtoMessage() {}
+
+func (x *ConfigInfo) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ConfigInfo.ProtoReflect.Descriptor instead.
+func (*ConfigInfo) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *ConfigInfo) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *ConfigInfo) GetVersion() int64 {
+	if x != nil {
+		return x.Version
+	}
+	return 0
+}
+
+func (x *ConfigInfo) GetStatus() ConfigStatus {
+	if x != nil {
+		return x.Status
+	}
+	return ConfigStatus_UNSET
+}
+
+func (x *ConfigInfo) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+// Define the Command information carried in the request
+type CommandInfo struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Type    string       `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`                        // Command's type
+	Name    string       `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`                        // Required, Command's unique identification
+	Status  ConfigStatus `protobuf:"varint,3,opt,name=status,proto3,enum=ConfigStatus" json:"status,omitempty"` // Command's status
+	Message string       `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"`                  // Optional error message
+}
+
+func (x *CommandInfo) Reset() {
+	*x = CommandInfo{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CommandInfo) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CommandInfo) ProtoMessage() {}
+
+func (x *CommandInfo) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CommandInfo.ProtoReflect.Descriptor instead.
+func (*CommandInfo) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *CommandInfo) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+func (x *CommandInfo) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *CommandInfo) GetStatus() ConfigStatus {
+	if x != nil {
+		return x.Status
+	}
+	return ConfigStatus_UNSET
+}
+
+func (x *CommandInfo) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+// Define Agent's basic attributes
+type AgentAttributes struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Version  []byte            `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`                                                                                         // Agent's version
+	Ip       []byte            `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"`                                                                                                   // Agent's ip
+	Hostname []byte            `protobuf:"bytes,3,opt,name=hostname,proto3" json:"hostname,omitempty"`                                                                                       // Agent's hostname
+	Extras   map[string][]byte `protobuf:"bytes,100,rep,name=extras,proto3" json:"extras,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Agent's other attributes
+}
+
+func (x *AgentAttributes) Reset() {
+	*x = AgentAttributes{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AgentAttributes) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AgentAttributes) ProtoMessage() {}
+
+func (x *AgentAttributes) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AgentAttributes.ProtoReflect.Descriptor instead.
+func (*AgentAttributes) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *AgentAttributes) GetVersion() []byte {
+	if x != nil {
+		return x.Version
+	}
+	return nil
+}
+
+func (x *AgentAttributes) GetIp() []byte {
+	if x != nil {
+		return x.Ip
+	}
+	return nil
+}
+
+func (x *AgentAttributes) GetHostname() []byte {
+	if x != nil {
+		return x.Hostname
+	}
+	return nil
+}
+
+func (x *AgentAttributes) GetExtras() map[string][]byte {
+	if x != nil {
+		return x.Extras
+	}
+	return nil
+}
+
+// Agent sends requests to the ConfigServer to get config updates and receive commands.
+type HeartbeatRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId       []byte           `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	SequenceNum     uint64           `protobuf:"varint,2,opt,name=sequence_num,json=sequenceNum,proto3" json:"sequence_num,omitempty"`             // Increment every request, for server to check sync status
+	Capabilities    uint64           `protobuf:"varint,3,opt,name=capabilities,proto3" json:"capabilities,omitempty"`                              // Bitmask of flags defined by AgentCapabilities enum
+	InstanceId      []byte           `protobuf:"bytes,4,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"`                 // Required, Agent's unique identification, consistent throughout the process lifecycle
+	AgentType       string           `protobuf:"bytes,5,opt,name=agent_type,json=agentType,proto3" json:"agent_type,omitempty"`                    // Required, Agent's type(ilogtail, ..)
+	Attributes      *AgentAttributes `protobuf:"bytes,6,opt,name=attributes,proto3" json:"attributes,omitempty"`                                   // Agent's basic attributes
+	Tags            []*AgentGroupTag `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty"`                                               // Agent's tags
+	RunningStatus   string           `protobuf:"bytes,8,opt,name=running_status,json=runningStatus,proto3" json:"running_status,omitempty"`        // Human readable running status
+	StartupTime     int64            `protobuf:"varint,9,opt,name=startup_time,json=startupTime,proto3" json:"startup_time,omitempty"`             // Required, Agent's startup time
+	PipelineConfigs []*ConfigInfo    `protobuf:"bytes,10,rep,name=pipeline_configs,json=pipelineConfigs,proto3" json:"pipeline_configs,omitempty"` // Information about the current PIPELINE_CONFIG held by the Agent
+	InstanceConfigs []*ConfigInfo    `protobuf:"bytes,11,rep,name=instance_configs,json=instanceConfigs,proto3" json:"instance_configs,omitempty"` // Information about the current AGENT_CONFIG held by the Agent
+	CustomCommands  []*CommandInfo   `protobuf:"bytes,12,rep,name=custom_commands,json=customCommands,proto3" json:"custom_commands,omitempty"`    // Information about command history
+	Flags           uint64           `protobuf:"varint,13,opt,name=flags,proto3" json:"flags,omitempty"`                                           // Predefined command flag
+	Opaque          []byte           `protobuf:"bytes,14,opt,name=opaque,proto3" json:"opaque,omitempty"`                                          // Opaque data for extension
+}
+
+func (x *HeartbeatRequest) Reset() {
+	*x = HeartbeatRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *HeartbeatRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*HeartbeatRequest) ProtoMessage() {}
+
+func (x *HeartbeatRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use HeartbeatRequest.ProtoReflect.Descriptor instead.
+func (*HeartbeatRequest) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *HeartbeatRequest) GetRequestId() []byte {
+	if x != nil {
+		return x.RequestId
+	}
+	return nil
+}
+
+func (x *HeartbeatRequest) GetSequenceNum() uint64 {
+	if x != nil {
+		return x.SequenceNum
+	}
+	return 0
+}
+
+func (x *HeartbeatRequest) GetCapabilities() uint64 {
+	if x != nil {
+		return x.Capabilities
+	}
+	return 0
+}
+
+func (x *HeartbeatRequest) GetInstanceId() []byte {
+	if x != nil {
+		return x.InstanceId
+	}
+	return nil
+}
+
+func (x *HeartbeatRequest) GetAgentType() string {
+	if x != nil {
+		return x.AgentType
+	}
+	return ""
+}
+
+func (x *HeartbeatRequest) GetAttributes() *AgentAttributes {
+	if x != nil {
+		return x.Attributes
+	}
+	return nil
+}
+
+func (x *HeartbeatRequest) GetTags() []*AgentGroupTag {
+	if x != nil {
+		return x.Tags
+	}
+	return nil
+}
+
+func (x *HeartbeatRequest) GetRunningStatus() string {
+	if x != nil {
+		return x.RunningStatus
+	}
+	return ""
+}
+
+func (x *HeartbeatRequest) GetStartupTime() int64 {
+	if x != nil {
+		return x.StartupTime
+	}
+	return 0
+}
+
+func (x *HeartbeatRequest) GetPipelineConfigs() []*ConfigInfo {
+	if x != nil {
+		return x.PipelineConfigs
+	}
+	return nil
+}
+
+func (x *HeartbeatRequest) GetInstanceConfigs() []*ConfigInfo {
+	if x != nil {
+		return x.InstanceConfigs
+	}
+	return nil
+}
+
+func (x *HeartbeatRequest) GetCustomCommands() []*CommandInfo {
+	if x != nil {
+		return x.CustomCommands
+	}
+	return nil
+}
+
+func (x *HeartbeatRequest) GetFlags() uint64 {
+	if x != nil {
+		return x.Flags
+	}
+	return 0
+}
+
+func (x *HeartbeatRequest) GetOpaque() []byte {
+	if x != nil {
+		return x.Opaque
+	}
+	return nil
+}
+
+// Define Config's detail
+type ConfigDetail struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name    string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`        // Required, Config's unique identification
+	Version int64  `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"` // Required, Config's version number or hash code
+	Detail  []byte `protobuf:"bytes,3,opt,name=detail,proto3" json:"detail,omitempty"`    // Required, Config's detail
+}
+
+func (x *ConfigDetail) Reset() {
+	*x = ConfigDetail{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ConfigDetail) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ConfigDetail) ProtoMessage() {}
+
+func (x *ConfigDetail) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ConfigDetail.ProtoReflect.Descriptor instead.
+func (*ConfigDetail) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *ConfigDetail) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *ConfigDetail) GetVersion() int64 {
+	if x != nil {
+		return x.Version
+	}
+	return 0
+}
+
+func (x *ConfigDetail) GetDetail() []byte {
+	if x != nil {
+		return x.Detail
+	}
+	return nil
+}
+
+type CommandDetail struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Type       string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`                                // Required, Command type
+	Name       string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`                                // Required, Command name
+	Detail     []byte `protobuf:"bytes,3,opt,name=detail,proto3" json:"detail,omitempty"`                            // Required, Command's detail
+	ExpireTime int64  `protobuf:"varint,4,opt,name=expire_time,json=expireTime,proto3" json:"expire_time,omitempty"` // After which the command can be safely removed from history
+}
+
+func (x *CommandDetail) Reset() {
+	*x = CommandDetail{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CommandDetail) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CommandDetail) ProtoMessage() {}
+
+func (x *CommandDetail) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CommandDetail.ProtoReflect.Descriptor instead.
+func (*CommandDetail) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *CommandDetail) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+func (x *CommandDetail) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *CommandDetail) GetDetail() []byte {
+	if x != nil {
+		return x.Detail
+	}
+	return nil
+}
+
+func (x *CommandDetail) GetExpireTime() int64 {
+	if x != nil {
+		return x.ExpireTime
+	}
+	return 0
+}
+
+// ConfigServer's response to Agent's request
+type HeartbeatResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId             []byte           `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse        *CommonResponse  `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`                        // Set common response
+	Capabilities          uint64           `protobuf:"varint,3,opt,name=capabilities,proto3" json:"capabilities,omitempty"`                                                 // Bitmask of flags defined by ServerCapabilities enum
+	PipelineConfigUpdates []*ConfigDetail  `protobuf:"bytes,4,rep,name=pipeline_config_updates,json=pipelineConfigUpdates,proto3" json:"pipeline_config_updates,omitempty"` // Agent's pipeline config update status
+	InstanceConfigUpdates []*ConfigDetail  `protobuf:"bytes,5,rep,name=instance_config_updates,json=instanceConfigUpdates,proto3" json:"instance_config_updates,omitempty"` // Agent's instance config update status
+	CustomCommandUpdates  []*CommandDetail `protobuf:"bytes,6,rep,name=custom_command_updates,json=customCommandUpdates,proto3" json:"custom_command_updates,omitempty"`    // Agent's commands updates
+	Flags                 uint64           `protobuf:"varint,7,opt,name=flags,proto3" json:"flags,omitempty"`                                                               // Predefined command flag
+	Opaque                []byte           `protobuf:"bytes,8,opt,name=opaque,proto3" json:"opaque,omitempty"`                                                              // Opaque data for extension
+}
+
+func (x *HeartbeatResponse) Reset() {
+	*x = HeartbeatResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *HeartbeatResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*HeartbeatResponse) ProtoMessage() {}
+
+func (x *HeartbeatResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use HeartbeatResponse.ProtoReflect.Descriptor instead.
+func (*HeartbeatResponse) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *HeartbeatResponse) GetRequestId() []byte {
+	if x != nil {
+		return x.RequestId
+	}
+	return nil
+}
+
+func (x *HeartbeatResponse) GetCommonResponse() *CommonResponse {
+	if x != nil {
+		return x.CommonResponse
+	}
+	return nil
+}
+
+func (x *HeartbeatResponse) GetCapabilities() uint64 {
+	if x != nil {
+		return x.Capabilities
+	}
+	return 0
+}
+
+func (x *HeartbeatResponse) GetPipelineConfigUpdates() []*ConfigDetail {
+	if x != nil {
+		return x.PipelineConfigUpdates
+	}
+	return nil
+}
+
+func (x *HeartbeatResponse) GetInstanceConfigUpdates() []*ConfigDetail {
+	if x != nil {
+		return x.InstanceConfigUpdates
+	}
+	return nil
+}
+
+func (x *HeartbeatResponse) GetCustomCommandUpdates() []*CommandDetail {
+	if x != nil {
+		return x.CustomCommandUpdates
+	}
+	return nil
+}
+
+func (x *HeartbeatResponse) GetFlags() uint64 {
+	if x != nil {
+		return x.Flags
+	}
+	return 0
+}
+
+func (x *HeartbeatResponse) GetOpaque() []byte {
+	if x != nil {
+		return x.Opaque
+	}
+	return nil
+}
+
+// API: /Agent/FetchPipelineConfig/
+// API: /Agent/FetchInstanceConfig/
+// Agent request to ConfigServer, pulling details of the config
+type FetchConfigRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId  []byte        `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	InstanceId []byte        `protobuf:"bytes,2,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"` // Agent's unique identification
+	ReqConfigs []*ConfigInfo `protobuf:"bytes,3,rep,name=req_configs,json=reqConfigs,proto3" json:"req_configs,omitempty"` // Config's name and version/hash
+}
+
+func (x *FetchConfigRequest) Reset() {
+	*x = FetchConfigRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FetchConfigRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FetchConfigRequest) ProtoMessage() {}
+
+func (x *FetchConfigRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FetchConfigRequest.ProtoReflect.Descriptor instead.
+func (*FetchConfigRequest) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *FetchConfigRequest) GetRequestId() []byte {
+	if x != nil {
+		return x.RequestId
+	}
+	return nil
+}
+
+func (x *FetchConfigRequest) GetInstanceId() []byte {
+	if x != nil {
+		return x.InstanceId
+	}
+	return nil
+}
+
+func (x *FetchConfigRequest) GetReqConfigs() []*ConfigInfo {
+	if x != nil {
+		return x.ReqConfigs
+	}
+	return nil
+}
+
+// ConfigServer response to Agent's request
+type FetchConfigResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
+	ConfigDetails  []*ConfigDetail `protobuf:"bytes,3,rep,name=config_details,json=configDetails,proto3" json:"config_details,omitempty"` // config detail
+}
+
+func (x *FetchConfigResponse) Reset() {
+	*x = FetchConfigResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FetchConfigResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FetchConfigResponse) ProtoMessage() {}
+
+func (x *FetchConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FetchConfigResponse.ProtoReflect.Descriptor instead.
+func (*FetchConfigResponse) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *FetchConfigResponse) GetRequestId() []byte {
+	if x != nil {
+		return x.RequestId
+	}
+	return nil
+}
+
+func (x *FetchConfigResponse) GetCommonResponse() *CommonResponse {
+	if x != nil {
+		return x.CommonResponse
+	}
+	return nil
+}
+
+func (x *FetchConfigResponse) GetConfigDetails() []*ConfigDetail {
+	if x != nil {
+		return x.ConfigDetails
+	}
+	return nil
+}
+
+type CommonResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Status       int32  `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
+	ErrorMessage []byte `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"`
+}
+
+func (x *CommonResponse) Reset() {
+	*x = CommonResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[10]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CommonResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CommonResponse) ProtoMessage() {}
+
+func (x *CommonResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[10]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CommonResponse.ProtoReflect.Descriptor instead.
+func (*CommonResponse) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *CommonResponse) GetStatus() int32 {
+	if x != nil {
+		return x.Status
+	}
+	return 0
+}
+
+func (x *CommonResponse) GetErrorMessage() []byte {
+	if x != nil {
+		return x.ErrorMessage
+	}
+	return nil
+}
+
+var File_agent_proto protoreflect.FileDescriptor
+
+var file_agent_proto_rawDesc = []byte{
+	0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x39, 0x0a,
+	0x0d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x12, 0x12,
+	0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x7b, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65,
+	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x76, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
+	0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x06,
+	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xc8, 0x01,
+	0x0a, 0x0f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+	0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69,
+	0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x68,
+	0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x68,
+	0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x65, 0x78, 0x74, 0x72, 0x61,
+	0x73, 0x18, 0x64, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41,
+	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x73,
+	0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x65, 0x78, 0x74, 0x72, 0x61, 0x73, 0x1a, 0x39, 0x0a,
+	0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
+	0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14,
+	0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76,
+	0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xad, 0x04, 0x0a, 0x10, 0x48, 0x65, 0x61,
+	0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
+	0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c,
+	0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x04, 0x52, 0x0b, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x4e, 0x75, 0x6d, 0x12,
+	0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
+	0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
+	0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+	0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79,
+	0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x54,
+	0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+	0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41,
+	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69,
+	0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
+	0x54, 0x61, 0x67, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x75, 0x6e,
+	0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0d, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65,
+	0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x54,
+	0x69, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x10, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x70, 0x69, 0x70, 0x65,
+	0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x36, 0x0a, 0x10, 0x69,
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18,
+	0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e,
+	0x66, 0x6f, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6f,
+	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x43,
+	0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74,
+	0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c,
+	0x61, 0x67, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73,
+	0x12, 0x16, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c,
+	0x52, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x22, 0x54, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07,
+	0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76,
+	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x70,
+	0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12,
+	0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74,
+	0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12,
+	0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65,
+	0x22, 0x92, 0x03, 0x0a, 0x11, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f,
+	0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f,
+	0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52,
+	0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
+	0x69, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x17, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x04,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74,
+	0x61, 0x69, 0x6c, 0x52, 0x15, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x17, 0x69, 0x6e,
+	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x70,
+	0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x15, 0x69, 0x6e, 0x73, 0x74,
+	0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+	0x73, 0x12, 0x44, 0x0a, 0x16, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
+	0x61, 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x52, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
+	0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73,
+	0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x16, 0x0a,
+	0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f,
+	0x70, 0x61, 0x71, 0x75, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x12, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
+	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x69,
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
+	0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x0b,
+	0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x0b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a,
+	0x72, 0x65, 0x71, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x13, 0x46,
+	0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
+	0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0e, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
+	0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
+	0x73, 0x22, 0x4d, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x65,
+	0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x2a, 0x40, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x41,
+	0x50, 0x50, 0x4c, 0x59, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x50, 0x50,
+	0x4c, 0x49, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44,
+	0x10, 0x03, 0x2a, 0x83, 0x01, 0x0a, 0x11, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61,
+	0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x1a, 0x55, 0x6e, 0x73, 0x70,
+	0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61,
+	0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65,
+	0x70, 0x74, 0x73, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x49, 0x6e,
+	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x10, 0x02, 0x12, 0x18,
+	0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43,
+	0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x04, 0x2a, 0x3a, 0x0a, 0x0c, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66,
+	0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61,
+	0x74, 0x65, 0x10, 0x01, 0x2a, 0xad, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43,
+	0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x55,
+	0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
+	0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10,
+	0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+	0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75,
+	0x73, 0x10, 0x02, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x49, 0x6e,
+	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74,
+	0x75, 0x73, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x43,
+	0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74,
+	0x75, 0x73, 0x10, 0x08, 0x2a, 0x80, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,
+	0x65, 0x64, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x75,
+	0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x65, 0x74,
+	0x63, 0x68, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x65, 0x74, 0x63,
+	0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44,
+	0x65, 0x74, 0x61, 0x69, 0x6c, 0x10, 0x04, 0x42, 0x0b, 0x5a, 0x09, 0x2f, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x76, 0x32, 0x3b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_agent_proto_rawDescOnce sync.Once
+	file_agent_proto_rawDescData = file_agent_proto_rawDesc
+)
+
+func file_agent_proto_rawDescGZIP() []byte {
+	file_agent_proto_rawDescOnce.Do(func() {
+		file_agent_proto_rawDescData = protoimpl.X.CompressGZIP(file_agent_proto_rawDescData)
+	})
+	return file_agent_proto_rawDescData
+}
+
+var file_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
+var file_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
+var file_agent_proto_goTypes = []any{
+	(ConfigStatus)(0),           // 0: ConfigStatus
+	(AgentCapabilities)(0),      // 1: AgentCapabilities
+	(RequestFlags)(0),           // 2: RequestFlags
+	(ServerCapabilities)(0),     // 3: ServerCapabilities
+	(ResponseFlags)(0),          // 4: ResponseFlags
+	(*AgentGroupTag)(nil),       // 5: AgentGroupTag
+	(*ConfigInfo)(nil),          // 6: ConfigInfo
+	(*CommandInfo)(nil),         // 7: CommandInfo
+	(*AgentAttributes)(nil),     // 8: AgentAttributes
+	(*HeartbeatRequest)(nil),    // 9: HeartbeatRequest
+	(*ConfigDetail)(nil),        // 10: ConfigDetail
+	(*CommandDetail)(nil),       // 11: CommandDetail
+	(*HeartbeatResponse)(nil),   // 12: HeartbeatResponse
+	(*FetchConfigRequest)(nil),  // 13: FetchConfigRequest
+	(*FetchConfigResponse)(nil), // 14: FetchConfigResponse
+	(*CommonResponse)(nil),      // 15: CommonResponse
+	nil,                         // 16: AgentAttributes.ExtrasEntry
+}
+var file_agent_proto_depIdxs = []int32{
+	0,  // 0: ConfigInfo.status:type_name -> ConfigStatus
+	0,  // 1: CommandInfo.status:type_name -> ConfigStatus
+	16, // 2: AgentAttributes.extras:type_name -> AgentAttributes.ExtrasEntry
+	8,  // 3: HeartbeatRequest.attributes:type_name -> AgentAttributes
+	5,  // 4: HeartbeatRequest.tags:type_name -> AgentGroupTag
+	6,  // 5: HeartbeatRequest.pipeline_configs:type_name -> ConfigInfo
+	6,  // 6: HeartbeatRequest.instance_configs:type_name -> ConfigInfo
+	7,  // 7: HeartbeatRequest.custom_commands:type_name -> CommandInfo
+	15, // 8: HeartbeatResponse.common_response:type_name -> CommonResponse
+	10, // 9: HeartbeatResponse.pipeline_config_updates:type_name -> ConfigDetail
+	10, // 10: HeartbeatResponse.instance_config_updates:type_name -> ConfigDetail
+	11, // 11: HeartbeatResponse.custom_command_updates:type_name -> CommandDetail
+	6,  // 12: FetchConfigRequest.req_configs:type_name -> ConfigInfo
+	15, // 13: FetchConfigResponse.common_response:type_name -> CommonResponse
+	10, // 14: FetchConfigResponse.config_details:type_name -> ConfigDetail
+	15, // [15:15] is the sub-list for method output_type
+	15, // [15:15] is the sub-list for method input_type
+	15, // [15:15] is the sub-list for extension type_name
+	15, // [15:15] is the sub-list for extension extendee
+	0,  // [0:15] is the sub-list for field type_name
+}
+
+func init() { file_agent_proto_init() }
+func file_agent_proto_init() {
+	if File_agent_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_agent_proto_msgTypes[0].Exporter = func(v any, i int) any {
+			switch v := v.(*AgentGroupTag); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[1].Exporter = func(v any, i int) any {
+			switch v := v.(*ConfigInfo); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[2].Exporter = func(v any, i int) any {
+			switch v := v.(*CommandInfo); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[3].Exporter = func(v any, i int) any {
+			switch v := v.(*AgentAttributes); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[4].Exporter = func(v any, i int) any {
+			switch v := v.(*HeartbeatRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[5].Exporter = func(v any, i int) any {
+			switch v := v.(*ConfigDetail); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[6].Exporter = func(v any, i int) any {
+			switch v := v.(*CommandDetail); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[7].Exporter = func(v any, i int) any {
+			switch v := v.(*HeartbeatResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[8].Exporter = func(v any, i int) any {
+			switch v := v.(*FetchConfigRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[9].Exporter = func(v any, i int) any {
+			switch v := v.(*FetchConfigResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[10].Exporter = func(v any, i int) any {
+			switch v := v.(*CommonResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_agent_proto_rawDesc,
+			NumEnums:      5,
+			NumMessages:   12,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_agent_proto_goTypes,
+		DependencyIndexes: file_agent_proto_depIdxs,
+		EnumInfos:         file_agent_proto_enumTypes,
+		MessageInfos:      file_agent_proto_msgTypes,
+	}.Build()
+	File_agent_proto = out.File
+	file_agent_proto_rawDesc = nil
+	file_agent_proto_goTypes = nil
+	file_agent_proto_depIdxs = nil
+}
diff --git a/config_server/service/proto/user.pb.go b/config_server/service/internal/protov2/user.pb.go
similarity index 51%
rename from config_server/service/proto/user.pb.go
rename to config_server/service/internal/protov2/user.pb.go
index 46278c419b..951367b407 100644
--- a/config_server/service/proto/user.pb.go
+++ b/config_server/service/internal/protov2/user.pb.go
@@ -1,10 +1,10 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.28.1
-// 	protoc        v3.6.1
+// 	protoc-gen-go v1.34.2
+// 	protoc        v3.20.0
 // source: user.proto
 
-package configserver_proto
+package protov2
 
 import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
@@ -20,17 +20,21 @@ const (
 	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
 )
 
-type AgentGroupTag struct {
+type Agent struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Name  string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
+	Capabilities  uint64           `protobuf:"varint,1,opt,name=capabilities,proto3" json:"capabilities,omitempty"`                       // Bitmask of flags defined by AgentCapabilities enum
+	InstanceId    []byte           `protobuf:"bytes,2,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"`          // Required, Agent's unique identification, consistent throughout the process lifecycle
+	AgentType     string           `protobuf:"bytes,3,opt,name=agent_type,json=agentType,proto3" json:"agent_type,omitempty"`             // Required, Agent's type(ilogtail, ..)
+	Attributes    *AgentAttributes `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"`                            // Agent's basic attributes
+	RunningStatus string           `protobuf:"bytes,5,opt,name=running_status,json=runningStatus,proto3" json:"running_status,omitempty"` // Human readable running status
+	StartupTime   int64            `protobuf:"varint,6,opt,name=startup_time,json=startupTime,proto3" json:"startup_time,omitempty"`      // Required, Agent's startup time
 }
 
-func (x *AgentGroupTag) Reset() {
-	*x = AgentGroupTag{}
+func (x *Agent) Reset() {
+	*x = Agent{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_user_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -38,13 +42,13 @@ func (x *AgentGroupTag) Reset() {
 	}
 }
 
-func (x *AgentGroupTag) String() string {
+func (x *Agent) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*AgentGroupTag) ProtoMessage() {}
+func (*Agent) ProtoMessage() {}
 
-func (x *AgentGroupTag) ProtoReflect() protoreflect.Message {
+func (x *Agent) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -56,119 +60,80 @@ func (x *AgentGroupTag) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use AgentGroupTag.ProtoReflect.Descriptor instead.
-func (*AgentGroupTag) Descriptor() ([]byte, []int) {
+// Deprecated: Use Agent.ProtoReflect.Descriptor instead.
+func (*Agent) Descriptor() ([]byte, []int) {
 	return file_user_proto_rawDescGZIP(), []int{0}
 }
 
-func (x *AgentGroupTag) GetName() string {
+func (x *Agent) GetCapabilities() uint64 {
 	if x != nil {
-		return x.Name
+		return x.Capabilities
 	}
-	return ""
+	return 0
 }
 
-func (x *AgentGroupTag) GetValue() string {
+func (x *Agent) GetInstanceId() []byte {
 	if x != nil {
-		return x.Value
-	}
-	return ""
-}
-
-type AgentGroup struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	GroupName   string           `protobuf:"bytes,1,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
-	Description string           `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
-	Tags        []*AgentGroupTag `protobuf:"bytes,3,rep,name=tags,proto3" json:"tags,omitempty"`
-}
-
-func (x *AgentGroup) Reset() {
-	*x = AgentGroup{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[1]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
+		return x.InstanceId
 	}
+	return nil
 }
 
-func (x *AgentGroup) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*AgentGroup) ProtoMessage() {}
-
-func (x *AgentGroup) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[1]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
+func (x *Agent) GetAgentType() string {
+	if x != nil {
+		return x.AgentType
 	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use AgentGroup.ProtoReflect.Descriptor instead.
-func (*AgentGroup) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{1}
+	return ""
 }
 
-func (x *AgentGroup) GetGroupName() string {
+func (x *Agent) GetAttributes() *AgentAttributes {
 	if x != nil {
-		return x.GroupName
+		return x.Attributes
 	}
-	return ""
+	return nil
 }
 
-func (x *AgentGroup) GetDescription() string {
+func (x *Agent) GetRunningStatus() string {
 	if x != nil {
-		return x.Description
+		return x.RunningStatus
 	}
 	return ""
 }
 
-func (x *AgentGroup) GetTags() []*AgentGroupTag {
+func (x *Agent) GetStartupTime() int64 {
 	if x != nil {
-		return x.Tags
+		return x.StartupTime
 	}
-	return nil
+	return 0
 }
 
-type Agent struct {
+type AgentConfigStatus struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	AgentId       string           `protobuf:"bytes,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`                   // Required, Agent's unique identification
-	AgentType     string           `protobuf:"bytes,2,opt,name=agent_type,json=agentType,proto3" json:"agent_type,omitempty"`             // Required, Agent's type(ilogtail, ..)
-	Attributes    *AgentAttributes `protobuf:"bytes,3,opt,name=attributes,proto3" json:"attributes,omitempty"`                            // Agent's basic attributes
-	Tags          []string         `protobuf:"bytes,4,rep,name=tags,proto3" json:"tags,omitempty"`                                        // Agent's tags
-	RunningStatus string           `protobuf:"bytes,5,opt,name=running_status,json=runningStatus,proto3" json:"running_status,omitempty"` // Required, Agent's running status
-	StartupTime   int64            `protobuf:"varint,6,opt,name=startup_time,json=startupTime,proto3" json:"startup_time,omitempty"`      // Required, Agent's startup time
-	Interval      int32            `protobuf:"varint,7,opt,name=interval,proto3" json:"interval,omitempty"`                               // Agent's heartbeat interval
+	Name    string       `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Status  ConfigStatus `protobuf:"varint,2,opt,name=status,proto3,enum=ConfigStatus" json:"status,omitempty"` // Config's status
+	Message string       `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`                  // Optional error message
 }
 
-func (x *Agent) Reset() {
-	*x = Agent{}
+func (x *AgentConfigStatus) Reset() {
+	*x = AgentConfigStatus{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[2]
+		mi := &file_user_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *Agent) String() string {
+func (x *AgentConfigStatus) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*Agent) ProtoMessage() {}
+func (*AgentConfigStatus) ProtoMessage() {}
 
-func (x *Agent) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[2]
+func (x *AgentConfigStatus) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -179,73 +144,45 @@ func (x *Agent) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use Agent.ProtoReflect.Descriptor instead.
-func (*Agent) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{2}
-}
-
-func (x *Agent) GetAgentId() string {
-	if x != nil {
-		return x.AgentId
-	}
-	return ""
+// Deprecated: Use AgentConfigStatus.ProtoReflect.Descriptor instead.
+func (*AgentConfigStatus) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{1}
 }
 
-func (x *Agent) GetAgentType() string {
+func (x *AgentConfigStatus) GetName() string {
 	if x != nil {
-		return x.AgentType
+		return x.Name
 	}
 	return ""
 }
 
-func (x *Agent) GetAttributes() *AgentAttributes {
-	if x != nil {
-		return x.Attributes
-	}
-	return nil
-}
-
-func (x *Agent) GetTags() []string {
+func (x *AgentConfigStatus) GetStatus() ConfigStatus {
 	if x != nil {
-		return x.Tags
+		return x.Status
 	}
-	return nil
+	return ConfigStatus_UNSET
 }
 
-func (x *Agent) GetRunningStatus() string {
+func (x *AgentConfigStatus) GetMessage() string {
 	if x != nil {
-		return x.RunningStatus
+		return x.Message
 	}
 	return ""
 }
 
-func (x *Agent) GetStartupTime() int64 {
-	if x != nil {
-		return x.StartupTime
-	}
-	return 0
-}
-
-func (x *Agent) GetInterval() int32 {
-	if x != nil {
-		return x.Interval
-	}
-	return 0
-}
-
 type CreateAgentGroupRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId  string      `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
-	AgentGroup *AgentGroup `protobuf:"bytes,2,opt,name=agent_group,json=agentGroup,proto3" json:"agent_group,omitempty"`
+	RequestId  []byte         `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	AgentGroup *AgentGroupTag `protobuf:"bytes,2,opt,name=agent_group,json=agentGroup,proto3" json:"agent_group,omitempty"`
 }
 
 func (x *CreateAgentGroupRequest) Reset() {
 	*x = CreateAgentGroupRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[3]
+		mi := &file_user_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -258,7 +195,7 @@ func (x *CreateAgentGroupRequest) String() string {
 func (*CreateAgentGroupRequest) ProtoMessage() {}
 
 func (x *CreateAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[3]
+	mi := &file_user_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -271,17 +208,17 @@ func (x *CreateAgentGroupRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*CreateAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{3}
+	return file_user_proto_rawDescGZIP(), []int{2}
 }
 
-func (x *CreateAgentGroupRequest) GetRequestId() string {
+func (x *CreateAgentGroupRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
-func (x *CreateAgentGroupRequest) GetAgentGroup() *AgentGroup {
+func (x *CreateAgentGroupRequest) GetAgentGroup() *AgentGroupTag {
 	if x != nil {
 		return x.AgentGroup
 	}
@@ -293,15 +230,14 @@ type CreateAgentGroupResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
 }
 
 func (x *CreateAgentGroupResponse) Reset() {
 	*x = CreateAgentGroupResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[4]
+		mi := &file_user_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -314,7 +250,7 @@ func (x *CreateAgentGroupResponse) String() string {
 func (*CreateAgentGroupResponse) ProtoMessage() {}
 
 func (x *CreateAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[4]
+	mi := &file_user_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -327,28 +263,21 @@ func (x *CreateAgentGroupResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*CreateAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{4}
-}
-
-func (x *CreateAgentGroupResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{3}
 }
 
-func (x *CreateAgentGroupResponse) GetCode() RespCode {
+func (x *CreateAgentGroupResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *CreateAgentGroupResponse) GetMessage() string {
+func (x *CreateAgentGroupResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
 type UpdateAgentGroupRequest struct {
@@ -356,14 +285,14 @@ type UpdateAgentGroupRequest struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId  string      `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
-	AgentGroup *AgentGroup `protobuf:"bytes,2,opt,name=agent_group,json=agentGroup,proto3" json:"agent_group,omitempty"`
+	RequestId  []byte         `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	AgentGroup *AgentGroupTag `protobuf:"bytes,2,opt,name=agent_group,json=agentGroup,proto3" json:"agent_group,omitempty"`
 }
 
 func (x *UpdateAgentGroupRequest) Reset() {
 	*x = UpdateAgentGroupRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[5]
+		mi := &file_user_proto_msgTypes[4]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -376,7 +305,7 @@ func (x *UpdateAgentGroupRequest) String() string {
 func (*UpdateAgentGroupRequest) ProtoMessage() {}
 
 func (x *UpdateAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[5]
+	mi := &file_user_proto_msgTypes[4]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -389,17 +318,17 @@ func (x *UpdateAgentGroupRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*UpdateAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{5}
+	return file_user_proto_rawDescGZIP(), []int{4}
 }
 
-func (x *UpdateAgentGroupRequest) GetRequestId() string {
+func (x *UpdateAgentGroupRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
-func (x *UpdateAgentGroupRequest) GetAgentGroup() *AgentGroup {
+func (x *UpdateAgentGroupRequest) GetAgentGroup() *AgentGroupTag {
 	if x != nil {
 		return x.AgentGroup
 	}
@@ -411,15 +340,14 @@ type UpdateAgentGroupResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
 }
 
 func (x *UpdateAgentGroupResponse) Reset() {
 	*x = UpdateAgentGroupResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[6]
+		mi := &file_user_proto_msgTypes[5]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -432,7 +360,7 @@ func (x *UpdateAgentGroupResponse) String() string {
 func (*UpdateAgentGroupResponse) ProtoMessage() {}
 
 func (x *UpdateAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[6]
+	mi := &file_user_proto_msgTypes[5]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -445,28 +373,21 @@ func (x *UpdateAgentGroupResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*UpdateAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{6}
-}
-
-func (x *UpdateAgentGroupResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{5}
 }
 
-func (x *UpdateAgentGroupResponse) GetCode() RespCode {
+func (x *UpdateAgentGroupResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *UpdateAgentGroupResponse) GetMessage() string {
+func (x *UpdateAgentGroupResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
 type DeleteAgentGroupRequest struct {
@@ -474,14 +395,14 @@ type DeleteAgentGroupRequest struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	RequestId []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
 	GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
 }
 
 func (x *DeleteAgentGroupRequest) Reset() {
 	*x = DeleteAgentGroupRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[7]
+		mi := &file_user_proto_msgTypes[6]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -494,7 +415,7 @@ func (x *DeleteAgentGroupRequest) String() string {
 func (*DeleteAgentGroupRequest) ProtoMessage() {}
 
 func (x *DeleteAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[7]
+	mi := &file_user_proto_msgTypes[6]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -507,14 +428,14 @@ func (x *DeleteAgentGroupRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*DeleteAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{7}
+	return file_user_proto_rawDescGZIP(), []int{6}
 }
 
-func (x *DeleteAgentGroupRequest) GetRequestId() string {
+func (x *DeleteAgentGroupRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
 func (x *DeleteAgentGroupRequest) GetGroupName() string {
@@ -529,15 +450,14 @@ type DeleteAgentGroupResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
 }
 
 func (x *DeleteAgentGroupResponse) Reset() {
 	*x = DeleteAgentGroupResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[8]
+		mi := &file_user_proto_msgTypes[7]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -550,7 +470,7 @@ func (x *DeleteAgentGroupResponse) String() string {
 func (*DeleteAgentGroupResponse) ProtoMessage() {}
 
 func (x *DeleteAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[8]
+	mi := &file_user_proto_msgTypes[7]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -563,28 +483,21 @@ func (x *DeleteAgentGroupResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*DeleteAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{8}
-}
-
-func (x *DeleteAgentGroupResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{7}
 }
 
-func (x *DeleteAgentGroupResponse) GetCode() RespCode {
+func (x *DeleteAgentGroupResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *DeleteAgentGroupResponse) GetMessage() string {
+func (x *DeleteAgentGroupResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
 type GetAgentGroupRequest struct {
@@ -592,14 +505,14 @@ type GetAgentGroupRequest struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	RequestId []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
 	GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
 }
 
 func (x *GetAgentGroupRequest) Reset() {
 	*x = GetAgentGroupRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[9]
+		mi := &file_user_proto_msgTypes[8]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -612,7 +525,7 @@ func (x *GetAgentGroupRequest) String() string {
 func (*GetAgentGroupRequest) ProtoMessage() {}
 
 func (x *GetAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[9]
+	mi := &file_user_proto_msgTypes[8]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -625,14 +538,14 @@ func (x *GetAgentGroupRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*GetAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{9}
+	return file_user_proto_rawDescGZIP(), []int{8}
 }
 
-func (x *GetAgentGroupRequest) GetRequestId() string {
+func (x *GetAgentGroupRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
 func (x *GetAgentGroupRequest) GetGroupName() string {
@@ -647,16 +560,15 @@ type GetAgentGroupResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId string      `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code       RespCode    `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message    string      `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
-	AgentGroup *AgentGroup `protobuf:"bytes,4,opt,name=agent_group,json=agentGroup,proto3" json:"agent_group,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
+	AgentGroup     *AgentGroupTag  `protobuf:"bytes,3,opt,name=agent_group,json=agentGroup,proto3" json:"agent_group,omitempty"`
 }
 
 func (x *GetAgentGroupResponse) Reset() {
 	*x = GetAgentGroupResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[10]
+		mi := &file_user_proto_msgTypes[9]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -669,7 +581,7 @@ func (x *GetAgentGroupResponse) String() string {
 func (*GetAgentGroupResponse) ProtoMessage() {}
 
 func (x *GetAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[10]
+	mi := &file_user_proto_msgTypes[9]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -682,31 +594,24 @@ func (x *GetAgentGroupResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*GetAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{10}
-}
-
-func (x *GetAgentGroupResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{9}
 }
 
-func (x *GetAgentGroupResponse) GetCode() RespCode {
+func (x *GetAgentGroupResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *GetAgentGroupResponse) GetMessage() string {
+func (x *GetAgentGroupResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
-func (x *GetAgentGroupResponse) GetAgentGroup() *AgentGroup {
+func (x *GetAgentGroupResponse) GetAgentGroup() *AgentGroupTag {
 	if x != nil {
 		return x.AgentGroup
 	}
@@ -718,13 +623,13 @@ type ListAgentGroupsRequest struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	RequestId []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
 }
 
 func (x *ListAgentGroupsRequest) Reset() {
 	*x = ListAgentGroupsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[11]
+		mi := &file_user_proto_msgTypes[10]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -737,7 +642,7 @@ func (x *ListAgentGroupsRequest) String() string {
 func (*ListAgentGroupsRequest) ProtoMessage() {}
 
 func (x *ListAgentGroupsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[11]
+	mi := &file_user_proto_msgTypes[10]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -750,14 +655,14 @@ func (x *ListAgentGroupsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListAgentGroupsRequest.ProtoReflect.Descriptor instead.
 func (*ListAgentGroupsRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{11}
+	return file_user_proto_rawDescGZIP(), []int{10}
 }
 
-func (x *ListAgentGroupsRequest) GetRequestId() string {
+func (x *ListAgentGroupsRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
 type ListAgentGroupsResponse struct {
@@ -765,16 +670,15 @@ type ListAgentGroupsResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId  string        `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code        RespCode      `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message     string        `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
-	AgentGroups []*AgentGroup `protobuf:"bytes,4,rep,name=agent_groups,json=agentGroups,proto3" json:"agent_groups,omitempty"`
+	RequestId      []byte           `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse  `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
+	AgentGroups    []*AgentGroupTag `protobuf:"bytes,4,rep,name=agent_groups,json=agentGroups,proto3" json:"agent_groups,omitempty"`
 }
 
 func (x *ListAgentGroupsResponse) Reset() {
 	*x = ListAgentGroupsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[12]
+		mi := &file_user_proto_msgTypes[11]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -787,7 +691,7 @@ func (x *ListAgentGroupsResponse) String() string {
 func (*ListAgentGroupsResponse) ProtoMessage() {}
 
 func (x *ListAgentGroupsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[12]
+	mi := &file_user_proto_msgTypes[11]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -800,50 +704,45 @@ func (x *ListAgentGroupsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListAgentGroupsResponse.ProtoReflect.Descriptor instead.
 func (*ListAgentGroupsResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{12}
-}
-
-func (x *ListAgentGroupsResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{11}
 }
 
-func (x *ListAgentGroupsResponse) GetCode() RespCode {
+func (x *ListAgentGroupsResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *ListAgentGroupsResponse) GetMessage() string {
+func (x *ListAgentGroupsResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
-func (x *ListAgentGroupsResponse) GetAgentGroups() []*AgentGroup {
+func (x *ListAgentGroupsResponse) GetAgentGroups() []*AgentGroupTag {
 	if x != nil {
 		return x.AgentGroups
 	}
 	return nil
 }
 
+// API: /User/CreatePipelineConfig
+// API: /User/CreateInstanceConfig
 type CreateConfigRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId    string        `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	RequestId    []byte        `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
 	ConfigDetail *ConfigDetail `protobuf:"bytes,2,opt,name=config_detail,json=configDetail,proto3" json:"config_detail,omitempty"`
 }
 
 func (x *CreateConfigRequest) Reset() {
 	*x = CreateConfigRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[13]
+		mi := &file_user_proto_msgTypes[12]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -856,7 +755,7 @@ func (x *CreateConfigRequest) String() string {
 func (*CreateConfigRequest) ProtoMessage() {}
 
 func (x *CreateConfigRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[13]
+	mi := &file_user_proto_msgTypes[12]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -869,14 +768,14 @@ func (x *CreateConfigRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateConfigRequest.ProtoReflect.Descriptor instead.
 func (*CreateConfigRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{13}
+	return file_user_proto_rawDescGZIP(), []int{12}
 }
 
-func (x *CreateConfigRequest) GetRequestId() string {
+func (x *CreateConfigRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
 func (x *CreateConfigRequest) GetConfigDetail() *ConfigDetail {
@@ -891,15 +790,14 @@ type CreateConfigResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
 }
 
 func (x *CreateConfigResponse) Reset() {
 	*x = CreateConfigResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[14]
+		mi := &file_user_proto_msgTypes[13]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -912,7 +810,7 @@ func (x *CreateConfigResponse) String() string {
 func (*CreateConfigResponse) ProtoMessage() {}
 
 func (x *CreateConfigResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[14]
+	mi := &file_user_proto_msgTypes[13]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -925,43 +823,38 @@ func (x *CreateConfigResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateConfigResponse.ProtoReflect.Descriptor instead.
 func (*CreateConfigResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{14}
-}
-
-func (x *CreateConfigResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{13}
 }
 
-func (x *CreateConfigResponse) GetCode() RespCode {
+func (x *CreateConfigResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *CreateConfigResponse) GetMessage() string {
+func (x *CreateConfigResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
+// API: /User/UpdatePipelineConfig
+// API: /User/UpdateInstanceConfig
 type UpdateConfigRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId    string        `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	RequestId    []byte        `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
 	ConfigDetail *ConfigDetail `protobuf:"bytes,2,opt,name=config_detail,json=configDetail,proto3" json:"config_detail,omitempty"`
 }
 
 func (x *UpdateConfigRequest) Reset() {
 	*x = UpdateConfigRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[15]
+		mi := &file_user_proto_msgTypes[14]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -974,7 +867,7 @@ func (x *UpdateConfigRequest) String() string {
 func (*UpdateConfigRequest) ProtoMessage() {}
 
 func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[15]
+	mi := &file_user_proto_msgTypes[14]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -987,14 +880,14 @@ func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateConfigRequest.ProtoReflect.Descriptor instead.
 func (*UpdateConfigRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{15}
+	return file_user_proto_rawDescGZIP(), []int{14}
 }
 
-func (x *UpdateConfigRequest) GetRequestId() string {
+func (x *UpdateConfigRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
 func (x *UpdateConfigRequest) GetConfigDetail() *ConfigDetail {
@@ -1009,15 +902,14 @@ type UpdateConfigResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
 }
 
 func (x *UpdateConfigResponse) Reset() {
 	*x = UpdateConfigResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[16]
+		mi := &file_user_proto_msgTypes[15]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1030,7 +922,7 @@ func (x *UpdateConfigResponse) String() string {
 func (*UpdateConfigResponse) ProtoMessage() {}
 
 func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[16]
+	mi := &file_user_proto_msgTypes[15]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1043,43 +935,38 @@ func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateConfigResponse.ProtoReflect.Descriptor instead.
 func (*UpdateConfigResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{16}
-}
-
-func (x *UpdateConfigResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{15}
 }
 
-func (x *UpdateConfigResponse) GetCode() RespCode {
+func (x *UpdateConfigResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *UpdateConfigResponse) GetMessage() string {
+func (x *UpdateConfigResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
+// API: /User/DeletePipelineConfig
+// API: /User/DeleteInstanceConfig
 type DeleteConfigRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId  string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	RequestId  []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
 	ConfigName string `protobuf:"bytes,2,opt,name=config_name,json=configName,proto3" json:"config_name,omitempty"`
 }
 
 func (x *DeleteConfigRequest) Reset() {
 	*x = DeleteConfigRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[17]
+		mi := &file_user_proto_msgTypes[16]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1092,7 +979,7 @@ func (x *DeleteConfigRequest) String() string {
 func (*DeleteConfigRequest) ProtoMessage() {}
 
 func (x *DeleteConfigRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[17]
+	mi := &file_user_proto_msgTypes[16]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1105,14 +992,14 @@ func (x *DeleteConfigRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteConfigRequest.ProtoReflect.Descriptor instead.
 func (*DeleteConfigRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{17}
+	return file_user_proto_rawDescGZIP(), []int{16}
 }
 
-func (x *DeleteConfigRequest) GetRequestId() string {
+func (x *DeleteConfigRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
 func (x *DeleteConfigRequest) GetConfigName() string {
@@ -1127,15 +1014,14 @@ type DeleteConfigResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
 }
 
 func (x *DeleteConfigResponse) Reset() {
 	*x = DeleteConfigResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[18]
+		mi := &file_user_proto_msgTypes[17]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1148,6 +1034,63 @@ func (x *DeleteConfigResponse) String() string {
 func (*DeleteConfigResponse) ProtoMessage() {}
 
 func (x *DeleteConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[17]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteConfigResponse.ProtoReflect.Descriptor instead.
+func (*DeleteConfigResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{17}
+}
+
+func (x *DeleteConfigResponse) GetRequestId() []byte {
+	if x != nil {
+		return x.RequestId
+	}
+	return nil
+}
+
+func (x *DeleteConfigResponse) GetCommonResponse() *CommonResponse {
+	if x != nil {
+		return x.CommonResponse
+	}
+	return nil
+}
+
+// API: /User/GetPipelineConfig
+// API: /User/GetInstanceConfig
+type GetConfigRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId  []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	ConfigName string `protobuf:"bytes,2,opt,name=config_name,json=configName,proto3" json:"config_name,omitempty"`
+}
+
+func (x *GetConfigRequest) Reset() {
+	*x = GetConfigRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[18]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetConfigRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetConfigRequest) ProtoMessage() {}
+
+func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[18]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -1159,58 +1102,116 @@ func (x *DeleteConfigResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use DeleteConfigResponse.ProtoReflect.Descriptor instead.
-func (*DeleteConfigResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{18}
+// Deprecated: Use GetConfigRequest.ProtoReflect.Descriptor instead.
+func (*GetConfigRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{18}
+}
+
+func (x *GetConfigRequest) GetRequestId() []byte {
+	if x != nil {
+		return x.RequestId
+	}
+	return nil
+}
+
+func (x *GetConfigRequest) GetConfigName() string {
+	if x != nil {
+		return x.ConfigName
+	}
+	return ""
+}
+
+type GetConfigResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
+	ConfigDetail   *ConfigDetail   `protobuf:"bytes,3,opt,name=config_detail,json=configDetail,proto3" json:"config_detail,omitempty"`
+}
+
+func (x *GetConfigResponse) Reset() {
+	*x = GetConfigResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[19]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetConfigResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetConfigResponse) ProtoMessage() {}
+
+func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[19]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetConfigResponse.ProtoReflect.Descriptor instead.
+func (*GetConfigResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{19}
 }
 
-func (x *DeleteConfigResponse) GetResponseId() string {
+func (x *GetConfigResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.ResponseId
+		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
-func (x *DeleteConfigResponse) GetCode() RespCode {
+func (x *GetConfigResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Code
+		return x.CommonResponse
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *DeleteConfigResponse) GetMessage() string {
+func (x *GetConfigResponse) GetConfigDetail() *ConfigDetail {
 	if x != nil {
-		return x.Message
+		return x.ConfigDetail
 	}
-	return ""
+	return nil
 }
 
-type GetConfigRequest struct {
+// API: /User/GetPipelineConfigStatusList
+// API: /User/GetInstanceConfigStatusList
+type GetConfigStatusListRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId  string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
-	ConfigName string `protobuf:"bytes,2,opt,name=config_name,json=configName,proto3" json:"config_name,omitempty"`
+	RequestId  []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	InstanceId []byte `protobuf:"bytes,2,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"`
 }
 
-func (x *GetConfigRequest) Reset() {
-	*x = GetConfigRequest{}
+func (x *GetConfigStatusListRequest) Reset() {
+	*x = GetConfigStatusListRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[19]
+		mi := &file_user_proto_msgTypes[20]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetConfigRequest) String() string {
+func (x *GetConfigStatusListRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetConfigRequest) ProtoMessage() {}
+func (*GetConfigStatusListRequest) ProtoMessage() {}
 
-func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[19]
+func (x *GetConfigStatusListRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[20]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1221,53 +1222,52 @@ func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetConfigRequest.ProtoReflect.Descriptor instead.
-func (*GetConfigRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{19}
+// Deprecated: Use GetConfigStatusListRequest.ProtoReflect.Descriptor instead.
+func (*GetConfigStatusListRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{20}
 }
 
-func (x *GetConfigRequest) GetRequestId() string {
+func (x *GetConfigStatusListRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
-func (x *GetConfigRequest) GetConfigName() string {
+func (x *GetConfigStatusListRequest) GetInstanceId() []byte {
 	if x != nil {
-		return x.ConfigName
+		return x.InstanceId
 	}
-	return ""
+	return nil
 }
 
-type GetConfigResponse struct {
+type GetConfigStatusListResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId   string        `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code         RespCode      `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message      string        `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
-	ConfigDetail *ConfigDetail `protobuf:"bytes,4,opt,name=config_detail,json=configDetail,proto3" json:"config_detail,omitempty"`
+	RequestId         []byte               `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse    *CommonResponse      `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
+	AgentConfigStatus []*AgentConfigStatus `protobuf:"bytes,3,rep,name=agent_config_status,json=agentConfigStatus,proto3" json:"agent_config_status,omitempty"`
 }
 
-func (x *GetConfigResponse) Reset() {
-	*x = GetConfigResponse{}
+func (x *GetConfigStatusListResponse) Reset() {
+	*x = GetConfigStatusListResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[20]
+		mi := &file_user_proto_msgTypes[21]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
 }
 
-func (x *GetConfigResponse) String() string {
+func (x *GetConfigStatusListResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetConfigResponse) ProtoMessage() {}
+func (*GetConfigStatusListResponse) ProtoMessage() {}
 
-func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[20]
+func (x *GetConfigStatusListResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[21]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1278,51 +1278,46 @@ func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetConfigResponse.ProtoReflect.Descriptor instead.
-func (*GetConfigResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{20}
-}
-
-func (x *GetConfigResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+// Deprecated: Use GetConfigStatusListResponse.ProtoReflect.Descriptor instead.
+func (*GetConfigStatusListResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{21}
 }
 
-func (x *GetConfigResponse) GetCode() RespCode {
+func (x *GetConfigStatusListResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *GetConfigResponse) GetMessage() string {
+func (x *GetConfigStatusListResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
-func (x *GetConfigResponse) GetConfigDetail() *ConfigDetail {
+func (x *GetConfigStatusListResponse) GetAgentConfigStatus() []*AgentConfigStatus {
 	if x != nil {
-		return x.ConfigDetail
+		return x.AgentConfigStatus
 	}
 	return nil
 }
 
+// API: /User/ListPipelineConfigs
+// API: /User/ListInstanceConfigs
 type ListConfigsRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	RequestId []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
 }
 
 func (x *ListConfigsRequest) Reset() {
 	*x = ListConfigsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[21]
+		mi := &file_user_proto_msgTypes[22]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1335,7 +1330,7 @@ func (x *ListConfigsRequest) String() string {
 func (*ListConfigsRequest) ProtoMessage() {}
 
 func (x *ListConfigsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[21]
+	mi := &file_user_proto_msgTypes[22]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1348,14 +1343,14 @@ func (x *ListConfigsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListConfigsRequest.ProtoReflect.Descriptor instead.
 func (*ListConfigsRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{21}
+	return file_user_proto_rawDescGZIP(), []int{22}
 }
 
-func (x *ListConfigsRequest) GetRequestId() string {
+func (x *ListConfigsRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
 type ListConfigsResponse struct {
@@ -1363,16 +1358,15 @@ type ListConfigsResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId    string          `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code          RespCode        `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message       string          `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
-	ConfigDetails []*ConfigDetail `protobuf:"bytes,4,rep,name=config_details,json=configDetails,proto3" json:"config_details,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
+	ConfigDetails  []*ConfigDetail `protobuf:"bytes,3,rep,name=config_details,json=configDetails,proto3" json:"config_details,omitempty"`
 }
 
 func (x *ListConfigsResponse) Reset() {
 	*x = ListConfigsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[22]
+		mi := &file_user_proto_msgTypes[23]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1385,7 +1379,7 @@ func (x *ListConfigsResponse) String() string {
 func (*ListConfigsResponse) ProtoMessage() {}
 
 func (x *ListConfigsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[22]
+	mi := &file_user_proto_msgTypes[23]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1398,28 +1392,21 @@ func (x *ListConfigsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListConfigsResponse.ProtoReflect.Descriptor instead.
 func (*ListConfigsResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{22}
-}
-
-func (x *ListConfigsResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{23}
 }
 
-func (x *ListConfigsResponse) GetCode() RespCode {
+func (x *ListConfigsResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *ListConfigsResponse) GetMessage() string {
+func (x *ListConfigsResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
 func (x *ListConfigsResponse) GetConfigDetails() []*ConfigDetail {
@@ -1429,12 +1416,14 @@ func (x *ListConfigsResponse) GetConfigDetails() []*ConfigDetail {
 	return nil
 }
 
+// API: /User/ApplyPipelineConfigToAgentGroup
+// API: /User/ApplyInstanceConfigToAgentGroup
 type ApplyConfigToAgentGroupRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId  string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	RequestId  []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
 	ConfigName string `protobuf:"bytes,2,opt,name=config_name,json=configName,proto3" json:"config_name,omitempty"`
 	GroupName  string `protobuf:"bytes,3,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
 }
@@ -1442,7 +1431,7 @@ type ApplyConfigToAgentGroupRequest struct {
 func (x *ApplyConfigToAgentGroupRequest) Reset() {
 	*x = ApplyConfigToAgentGroupRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[23]
+		mi := &file_user_proto_msgTypes[24]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1455,7 +1444,7 @@ func (x *ApplyConfigToAgentGroupRequest) String() string {
 func (*ApplyConfigToAgentGroupRequest) ProtoMessage() {}
 
 func (x *ApplyConfigToAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[23]
+	mi := &file_user_proto_msgTypes[24]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1468,14 +1457,14 @@ func (x *ApplyConfigToAgentGroupRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplyConfigToAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*ApplyConfigToAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{23}
+	return file_user_proto_rawDescGZIP(), []int{24}
 }
 
-func (x *ApplyConfigToAgentGroupRequest) GetRequestId() string {
+func (x *ApplyConfigToAgentGroupRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
 func (x *ApplyConfigToAgentGroupRequest) GetConfigName() string {
@@ -1497,15 +1486,14 @@ type ApplyConfigToAgentGroupResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
 }
 
 func (x *ApplyConfigToAgentGroupResponse) Reset() {
 	*x = ApplyConfigToAgentGroupResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[24]
+		mi := &file_user_proto_msgTypes[25]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1518,7 +1506,7 @@ func (x *ApplyConfigToAgentGroupResponse) String() string {
 func (*ApplyConfigToAgentGroupResponse) ProtoMessage() {}
 
 func (x *ApplyConfigToAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[24]
+	mi := &file_user_proto_msgTypes[25]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1531,36 +1519,31 @@ func (x *ApplyConfigToAgentGroupResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplyConfigToAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*ApplyConfigToAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{24}
-}
-
-func (x *ApplyConfigToAgentGroupResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{25}
 }
 
-func (x *ApplyConfigToAgentGroupResponse) GetCode() RespCode {
+func (x *ApplyConfigToAgentGroupResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *ApplyConfigToAgentGroupResponse) GetMessage() string {
+func (x *ApplyConfigToAgentGroupResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
+// API: /User/RemovePipelineConfigFromAgentGroup/
+// API: /User/RemoveInstanceConfigFromAgentGroup/
 type RemoveConfigFromAgentGroupRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId  string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	RequestId  []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
 	ConfigName string `protobuf:"bytes,2,opt,name=config_name,json=configName,proto3" json:"config_name,omitempty"`
 	GroupName  string `protobuf:"bytes,3,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
 }
@@ -1568,7 +1551,7 @@ type RemoveConfigFromAgentGroupRequest struct {
 func (x *RemoveConfigFromAgentGroupRequest) Reset() {
 	*x = RemoveConfigFromAgentGroupRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[25]
+		mi := &file_user_proto_msgTypes[26]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1581,7 +1564,7 @@ func (x *RemoveConfigFromAgentGroupRequest) String() string {
 func (*RemoveConfigFromAgentGroupRequest) ProtoMessage() {}
 
 func (x *RemoveConfigFromAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[25]
+	mi := &file_user_proto_msgTypes[26]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1594,14 +1577,14 @@ func (x *RemoveConfigFromAgentGroupRequest) ProtoReflect() protoreflect.Message
 
 // Deprecated: Use RemoveConfigFromAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*RemoveConfigFromAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{25}
+	return file_user_proto_rawDescGZIP(), []int{26}
 }
 
-func (x *RemoveConfigFromAgentGroupRequest) GetRequestId() string {
+func (x *RemoveConfigFromAgentGroupRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
 func (x *RemoveConfigFromAgentGroupRequest) GetConfigName() string {
@@ -1623,15 +1606,14 @@ type RemoveConfigFromAgentGroupResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
 }
 
 func (x *RemoveConfigFromAgentGroupResponse) Reset() {
 	*x = RemoveConfigFromAgentGroupResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[26]
+		mi := &file_user_proto_msgTypes[27]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1644,7 +1626,7 @@ func (x *RemoveConfigFromAgentGroupResponse) String() string {
 func (*RemoveConfigFromAgentGroupResponse) ProtoMessage() {}
 
 func (x *RemoveConfigFromAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[26]
+	mi := &file_user_proto_msgTypes[27]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1657,43 +1639,38 @@ func (x *RemoveConfigFromAgentGroupResponse) ProtoReflect() protoreflect.Message
 
 // Deprecated: Use RemoveConfigFromAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*RemoveConfigFromAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{26}
-}
-
-func (x *RemoveConfigFromAgentGroupResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{27}
 }
 
-func (x *RemoveConfigFromAgentGroupResponse) GetCode() RespCode {
+func (x *RemoveConfigFromAgentGroupResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *RemoveConfigFromAgentGroupResponse) GetMessage() string {
+func (x *RemoveConfigFromAgentGroupResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
+// API: /User/GetAppliedPipelineConfigsForAgentGroup/
+// API: /User/GetAppliedInstanceConfigsForAgentGroup/
 type GetAppliedConfigsForAgentGroupRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	RequestId []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
 	GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
 }
 
 func (x *GetAppliedConfigsForAgentGroupRequest) Reset() {
 	*x = GetAppliedConfigsForAgentGroupRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[27]
+		mi := &file_user_proto_msgTypes[28]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1706,7 +1683,7 @@ func (x *GetAppliedConfigsForAgentGroupRequest) String() string {
 func (*GetAppliedConfigsForAgentGroupRequest) ProtoMessage() {}
 
 func (x *GetAppliedConfigsForAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[27]
+	mi := &file_user_proto_msgTypes[28]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1719,14 +1696,14 @@ func (x *GetAppliedConfigsForAgentGroupRequest) ProtoReflect() protoreflect.Mess
 
 // Deprecated: Use GetAppliedConfigsForAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*GetAppliedConfigsForAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{27}
+	return file_user_proto_rawDescGZIP(), []int{28}
 }
 
-func (x *GetAppliedConfigsForAgentGroupRequest) GetRequestId() string {
+func (x *GetAppliedConfigsForAgentGroupRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
 func (x *GetAppliedConfigsForAgentGroupRequest) GetGroupName() string {
@@ -1741,16 +1718,15 @@ type GetAppliedConfigsForAgentGroupResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId  string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code        RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message     string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
-	ConfigNames []string `protobuf:"bytes,4,rep,name=config_names,json=configNames,proto3" json:"config_names,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
+	ConfigNames    []string        `protobuf:"bytes,4,rep,name=config_names,json=configNames,proto3" json:"config_names,omitempty"`
 }
 
 func (x *GetAppliedConfigsForAgentGroupResponse) Reset() {
 	*x = GetAppliedConfigsForAgentGroupResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[28]
+		mi := &file_user_proto_msgTypes[29]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1763,7 +1739,7 @@ func (x *GetAppliedConfigsForAgentGroupResponse) String() string {
 func (*GetAppliedConfigsForAgentGroupResponse) ProtoMessage() {}
 
 func (x *GetAppliedConfigsForAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[28]
+	mi := &file_user_proto_msgTypes[29]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1776,28 +1752,21 @@ func (x *GetAppliedConfigsForAgentGroupResponse) ProtoReflect() protoreflect.Mes
 
 // Deprecated: Use GetAppliedConfigsForAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*GetAppliedConfigsForAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{28}
-}
-
-func (x *GetAppliedConfigsForAgentGroupResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{29}
 }
 
-func (x *GetAppliedConfigsForAgentGroupResponse) GetCode() RespCode {
+func (x *GetAppliedConfigsForAgentGroupResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *GetAppliedConfigsForAgentGroupResponse) GetMessage() string {
+func (x *GetAppliedConfigsForAgentGroupResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
 func (x *GetAppliedConfigsForAgentGroupResponse) GetConfigNames() []string {
@@ -1807,19 +1776,21 @@ func (x *GetAppliedConfigsForAgentGroupResponse) GetConfigNames() []string {
 	return nil
 }
 
+// API: /User/GetAppliedAgentGroupsWithPipelineConfig/
+// API: /User/GetAppliedAgentGroupsWithInstanceConfig/
 type GetAppliedAgentGroupsRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId  string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	RequestId  []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
 	ConfigName string `protobuf:"bytes,2,opt,name=config_name,json=configName,proto3" json:"config_name,omitempty"`
 }
 
 func (x *GetAppliedAgentGroupsRequest) Reset() {
 	*x = GetAppliedAgentGroupsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[29]
+		mi := &file_user_proto_msgTypes[30]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1832,7 +1803,7 @@ func (x *GetAppliedAgentGroupsRequest) String() string {
 func (*GetAppliedAgentGroupsRequest) ProtoMessage() {}
 
 func (x *GetAppliedAgentGroupsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[29]
+	mi := &file_user_proto_msgTypes[30]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1845,14 +1816,14 @@ func (x *GetAppliedAgentGroupsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAppliedAgentGroupsRequest.ProtoReflect.Descriptor instead.
 func (*GetAppliedAgentGroupsRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{29}
+	return file_user_proto_rawDescGZIP(), []int{30}
 }
 
-func (x *GetAppliedAgentGroupsRequest) GetRequestId() string {
+func (x *GetAppliedAgentGroupsRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
 func (x *GetAppliedAgentGroupsRequest) GetConfigName() string {
@@ -1867,16 +1838,15 @@ type GetAppliedAgentGroupsResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId      string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code            RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message         string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
-	AgentGroupNames []string `protobuf:"bytes,4,rep,name=agent_group_names,json=agentGroupNames,proto3" json:"agent_group_names,omitempty"`
+	RequestId       []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse  *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
+	AgentGroupNames []string        `protobuf:"bytes,3,rep,name=agent_group_names,json=agentGroupNames,proto3" json:"agent_group_names,omitempty"`
 }
 
 func (x *GetAppliedAgentGroupsResponse) Reset() {
 	*x = GetAppliedAgentGroupsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[30]
+		mi := &file_user_proto_msgTypes[31]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1889,7 +1859,7 @@ func (x *GetAppliedAgentGroupsResponse) String() string {
 func (*GetAppliedAgentGroupsResponse) ProtoMessage() {}
 
 func (x *GetAppliedAgentGroupsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[30]
+	mi := &file_user_proto_msgTypes[31]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1902,28 +1872,21 @@ func (x *GetAppliedAgentGroupsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAppliedAgentGroupsResponse.ProtoReflect.Descriptor instead.
 func (*GetAppliedAgentGroupsResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{30}
-}
-
-func (x *GetAppliedAgentGroupsResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{31}
 }
 
-func (x *GetAppliedAgentGroupsResponse) GetCode() RespCode {
+func (x *GetAppliedAgentGroupsResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *GetAppliedAgentGroupsResponse) GetMessage() string {
+func (x *GetAppliedAgentGroupsResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
 func (x *GetAppliedAgentGroupsResponse) GetAgentGroupNames() []string {
@@ -1938,14 +1901,14 @@ type ListAgentsRequest struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	RequestId []byte `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
 	GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
 }
 
 func (x *ListAgentsRequest) Reset() {
 	*x = ListAgentsRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[31]
+		mi := &file_user_proto_msgTypes[32]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1958,7 +1921,7 @@ func (x *ListAgentsRequest) String() string {
 func (*ListAgentsRequest) ProtoMessage() {}
 
 func (x *ListAgentsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[31]
+	mi := &file_user_proto_msgTypes[32]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1971,14 +1934,14 @@ func (x *ListAgentsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListAgentsRequest.ProtoReflect.Descriptor instead.
 func (*ListAgentsRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{31}
+	return file_user_proto_rawDescGZIP(), []int{32}
 }
 
-func (x *ListAgentsRequest) GetRequestId() string {
+func (x *ListAgentsRequest) GetRequestId() []byte {
 	if x != nil {
 		return x.RequestId
 	}
-	return ""
+	return nil
 }
 
 func (x *ListAgentsRequest) GetGroupName() string {
@@ -1993,16 +1956,15 @@ type ListAgentsResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
-	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
-	Agents     []*Agent `protobuf:"bytes,4,rep,name=agents,proto3" json:"agents,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
+	Agents         []*Agent        `protobuf:"bytes,3,rep,name=agents,proto3" json:"agents,omitempty"`
 }
 
 func (x *ListAgentsResponse) Reset() {
 	*x = ListAgentsResponse{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[32]
+		mi := &file_user_proto_msgTypes[33]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2015,7 +1977,7 @@ func (x *ListAgentsResponse) String() string {
 func (*ListAgentsResponse) ProtoMessage() {}
 
 func (x *ListAgentsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[32]
+	mi := &file_user_proto_msgTypes[33]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2028,28 +1990,21 @@ func (x *ListAgentsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListAgentsResponse.ProtoReflect.Descriptor instead.
 func (*ListAgentsResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{32}
-}
-
-func (x *ListAgentsResponse) GetResponseId() string {
-	if x != nil {
-		return x.ResponseId
-	}
-	return ""
+	return file_user_proto_rawDescGZIP(), []int{33}
 }
 
-func (x *ListAgentsResponse) GetCode() RespCode {
+func (x *ListAgentsResponse) GetRequestId() []byte {
 	if x != nil {
-		return x.Code
+		return x.RequestId
 	}
-	return RespCode_ACCEPT
+	return nil
 }
 
-func (x *ListAgentsResponse) GetMessage() string {
+func (x *ListAgentsResponse) GetCommonResponse() *CommonResponse {
 	if x != nil {
-		return x.Message
+		return x.CommonResponse
 	}
-	return ""
+	return nil
 }
 
 func (x *ListAgentsResponse) GetAgents() []*Agent {
@@ -2062,288 +2017,267 @@ func (x *ListAgentsResponse) GetAgents() []*Agent {
 var File_user_proto protoreflect.FileDescriptor
 
 var file_user_proto_rawDesc = []byte{
-	0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x1a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x39, 0x0a,
-	0x0d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x12, 0x12,
-	0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
-	0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x84, 0x01, 0x0a, 0x0a, 0x41, 0x67, 0x65,
-	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70,
-	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f,
-	0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
-	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,
-	0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73,
-	0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73,
-	0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e,
-	0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x22,
-	0x80, 0x02, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x67, 0x65,
-	0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65,
-	0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79,
-	0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x54,
-	0x79, 0x70, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
-	0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65,
-	0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74,
-	0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73,
-	0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x25, 0x0a, 0x0e,
-	0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x74,
-	0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74,
-	0x75, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76,
-	0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76,
-	0x61, 0x6c, 0x22, 0x79, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e,
-	0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
-	0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x3f, 0x0a, 0x0b,
-	0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
-	0x70, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x87, 0x01,
-	0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f,
-	0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63,
-	0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52,
-	0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a,
-	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
-	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x79, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74,
-	0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
-	0x64, 0x12, 0x3f, 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73,
-	0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e,
-	0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f,
-	0x75, 0x70, 0x22, 0x87, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65,
-	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64,
-	0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c,
-	0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f,
-	0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x57, 0x0a, 0x17,
-	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f,
-	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75,
-	0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+	0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0b, 0x61, 0x67,
+	0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe7, 0x01, 0x0a, 0x05, 0x41, 0x67,
+	0x65, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
+	0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62,
+	0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61,
+	0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69, 0x6e,
+	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x67, 0x65, 0x6e,
+	0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67,
+	0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69,
+	0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x41, 0x67,
+	0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61,
+	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x75, 0x6e,
+	0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0d, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65,
+	0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x54,
+	0x69, 0x6d, 0x65, 0x22, 0x68, 0x0a, 0x11, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x06,
+	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x69, 0x0a,
+	0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74,
+	0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41,
+	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52, 0x0a, 0x61, 0x67,
+	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x73, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61,
+	0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43,
+	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63,
+	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x0a,
+	0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74,
+	0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41,
+	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52, 0x0a, 0x61, 0x67,
+	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x73, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61,
+	0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43,
+	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63,
+	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x57, 0x0a,
+	0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70,
+	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f,
+	0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x73, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
 	0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52,
-	0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22,
-	0x54, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f,
-	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75,
-	0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xc5, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65,
-	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64,
-	0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c,
-	0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f,
-	0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3f, 0x0a, 0x0b,
-	0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
-	0x70, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x37, 0x0a,
-	0x16, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0xc9, 0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x41,
-	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52,
-	0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
-	0x41, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18,
-	0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65,
-	0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74,
-	0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
-	0x70, 0x73, 0x22, 0x7b, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69,
-	0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22,
-	0x83, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64,
-	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73,
-	0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d,
-	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65,
-	0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x7b, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x0d, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65,
-	0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65,
-	0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
-	0x69, 0x6c, 0x22, 0x83, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04,
-	0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
-	0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18,
-	0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x55, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65,
-	0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
+	0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x0a, 0x14, 0x47,
+	0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d,
+	0x65, 0x22, 0xa1, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
+	0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
+	0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f,
+	0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72,
+	0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e,
+	0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74,
+	0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x37, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65,
+	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
 	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f,
-	0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22,
-	0x83, 0x01, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64,
-	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73,
-	0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d,
-	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65,
-	0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x52, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xc7, 0x01, 0x0a, 0x11, 0x47, 0x65,
-	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64,
-	0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c,
-	0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f,
-	0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x45, 0x0a, 0x0d,
-	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76,
-	0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44,
-	0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74,
-	0x61, 0x69, 0x6c, 0x22, 0x33, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0xcb, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73,
-	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49,
-	0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
-	0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63,
-	0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x47, 0x0a,
-	0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18,
-	0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65,
-	0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44,
-	0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x7f, 0x0a, 0x1e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
-	0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75,
-	0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72,
-	0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x8e, 0x01, 0x0a, 0x1f, 0x41, 0x70, 0x70, 0x6c,
-	0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
-	0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04,
-	0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
-	0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18,
-	0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x21, 0x52, 0x65, 0x6d,
-	0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x67, 0x65,
-	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
-	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a,
-	0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d,
-	0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x91, 0x01,
-	0x0a, 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x72,
-	0x6f, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76,
-	0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64,
-	0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
-	0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
-	0x65, 0x22, 0x65, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x46, 0x6f, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
-	0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f,
-	0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67,
-	0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x26, 0x47, 0x65, 0x74,
-	0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x46, 0x6f,
-	0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f,
-	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65,
-	0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65,
-	0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
-	0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73,
-	0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61,
-	0x6d, 0x65, 0x73, 0x22, 0x5e, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65,
-	0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0xa5,
+	0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f,
+	0x75, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e,
+	0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74,
+	0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x68, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
+	0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x0d,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
+	0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
+	0x22, 0x6f, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+	0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x22, 0x68, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d,
+	0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x6f, 0x0a, 0x14, 0x55,
+	0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f,
+	0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f,
+	0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x0a, 0x13,
+	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75,
 	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
 	0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d,
 	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e,
-	0x61, 0x6d, 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69,
-	0x65, 0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72,
-	0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f,
-	0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
-	0x67, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75,
-	0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x61,
-	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x51,
-	0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d,
-	0x65, 0x22, 0xb4, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x73,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64,
-	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73,
-	0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d,
-	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65,
-	0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x18,
-	0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65,
-	0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74,
-	0x52, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x16, 0x5a, 0x14, 0x2e, 0x3b, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x61, 0x6d, 0x65, 0x22, 0x6f, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
+	0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f,
+	0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa0, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d,
+	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a,
+	0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d,
+	0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x5c, 0x0a, 0x1a, 0x47,
+	0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4c, 0x69,
+	0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74,
+	0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69,
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0xba, 0x01, 0x0a, 0x1b, 0x47, 0x65,
+	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4c, 0x69, 0x73,
+	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d,
+	0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x42, 0x0a, 0x13, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x12, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x52, 0x11, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x33, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
+	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0xa4, 0x01, 0x0a, 0x13,
+	0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f,
+	0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f,
+	0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0e,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74,
+	0x61, 0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x73, 0x22, 0x7f, 0x0a, 0x1e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e,
+	0x61, 0x6d, 0x65, 0x22, 0x7a, 0x0a, 0x1f, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f,
+	0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f,
+	0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52,
+	0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
+	0x82, 0x01, 0x0a, 0x21, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x46, 0x72, 0x6f, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70,
+	0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7d, 0x0a, 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f,
+	0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x65, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65,
+	0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x46, 0x6f, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74,
+	0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
+	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67,
+	0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x26, 0x47,
+	0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73,
+	0x46, 0x6f, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e,
+	0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e,
+	0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21,
+	0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04,
+	0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65,
+	0x73, 0x22, 0x5e, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x41,
+	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64,
+	0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d,
+	0x65, 0x22, 0xa4, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64,
+	0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f,
+	0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f,
+	0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x11,
+	0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
+	0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
+	0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74,
+	0x41, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
+	0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a,
+	0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x8d, 0x01, 0x0a, 0x12,
+	0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
+	0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x06, 0x61,
+	0x67, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x06, 0x2e, 0x41, 0x67,
+	0x65, 0x6e, 0x74, 0x52, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x0b, 0x5a, 0x09, 0x2f,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x76, 0x32, 0x3b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -2358,77 +2292,82 @@ func file_user_proto_rawDescGZIP() []byte {
 	return file_user_proto_rawDescData
 }
 
-var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 33)
-var file_user_proto_goTypes = []interface{}{
-	(*AgentGroupTag)(nil),                          // 0: configserver.proto.AgentGroupTag
-	(*AgentGroup)(nil),                             // 1: configserver.proto.AgentGroup
-	(*Agent)(nil),                                  // 2: configserver.proto.Agent
-	(*CreateAgentGroupRequest)(nil),                // 3: configserver.proto.CreateAgentGroupRequest
-	(*CreateAgentGroupResponse)(nil),               // 4: configserver.proto.CreateAgentGroupResponse
-	(*UpdateAgentGroupRequest)(nil),                // 5: configserver.proto.UpdateAgentGroupRequest
-	(*UpdateAgentGroupResponse)(nil),               // 6: configserver.proto.UpdateAgentGroupResponse
-	(*DeleteAgentGroupRequest)(nil),                // 7: configserver.proto.DeleteAgentGroupRequest
-	(*DeleteAgentGroupResponse)(nil),               // 8: configserver.proto.DeleteAgentGroupResponse
-	(*GetAgentGroupRequest)(nil),                   // 9: configserver.proto.GetAgentGroupRequest
-	(*GetAgentGroupResponse)(nil),                  // 10: configserver.proto.GetAgentGroupResponse
-	(*ListAgentGroupsRequest)(nil),                 // 11: configserver.proto.ListAgentGroupsRequest
-	(*ListAgentGroupsResponse)(nil),                // 12: configserver.proto.ListAgentGroupsResponse
-	(*CreateConfigRequest)(nil),                    // 13: configserver.proto.CreateConfigRequest
-	(*CreateConfigResponse)(nil),                   // 14: configserver.proto.CreateConfigResponse
-	(*UpdateConfigRequest)(nil),                    // 15: configserver.proto.UpdateConfigRequest
-	(*UpdateConfigResponse)(nil),                   // 16: configserver.proto.UpdateConfigResponse
-	(*DeleteConfigRequest)(nil),                    // 17: configserver.proto.DeleteConfigRequest
-	(*DeleteConfigResponse)(nil),                   // 18: configserver.proto.DeleteConfigResponse
-	(*GetConfigRequest)(nil),                       // 19: configserver.proto.GetConfigRequest
-	(*GetConfigResponse)(nil),                      // 20: configserver.proto.GetConfigResponse
-	(*ListConfigsRequest)(nil),                     // 21: configserver.proto.ListConfigsRequest
-	(*ListConfigsResponse)(nil),                    // 22: configserver.proto.ListConfigsResponse
-	(*ApplyConfigToAgentGroupRequest)(nil),         // 23: configserver.proto.ApplyConfigToAgentGroupRequest
-	(*ApplyConfigToAgentGroupResponse)(nil),        // 24: configserver.proto.ApplyConfigToAgentGroupResponse
-	(*RemoveConfigFromAgentGroupRequest)(nil),      // 25: configserver.proto.RemoveConfigFromAgentGroupRequest
-	(*RemoveConfigFromAgentGroupResponse)(nil),     // 26: configserver.proto.RemoveConfigFromAgentGroupResponse
-	(*GetAppliedConfigsForAgentGroupRequest)(nil),  // 27: configserver.proto.GetAppliedConfigsForAgentGroupRequest
-	(*GetAppliedConfigsForAgentGroupResponse)(nil), // 28: configserver.proto.GetAppliedConfigsForAgentGroupResponse
-	(*GetAppliedAgentGroupsRequest)(nil),           // 29: configserver.proto.GetAppliedAgentGroupsRequest
-	(*GetAppliedAgentGroupsResponse)(nil),          // 30: configserver.proto.GetAppliedAgentGroupsResponse
-	(*ListAgentsRequest)(nil),                      // 31: configserver.proto.ListAgentsRequest
-	(*ListAgentsResponse)(nil),                     // 32: configserver.proto.ListAgentsResponse
-	(*AgentAttributes)(nil),                        // 33: configserver.proto.AgentAttributes
-	(RespCode)(0),                                  // 34: configserver.proto.RespCode
-	(*ConfigDetail)(nil),                           // 35: configserver.proto.ConfigDetail
+var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 34)
+var file_user_proto_goTypes = []any{
+	(*Agent)(nil),                                  // 0: Agent
+	(*AgentConfigStatus)(nil),                      // 1: AgentConfigStatus
+	(*CreateAgentGroupRequest)(nil),                // 2: CreateAgentGroupRequest
+	(*CreateAgentGroupResponse)(nil),               // 3: CreateAgentGroupResponse
+	(*UpdateAgentGroupRequest)(nil),                // 4: UpdateAgentGroupRequest
+	(*UpdateAgentGroupResponse)(nil),               // 5: UpdateAgentGroupResponse
+	(*DeleteAgentGroupRequest)(nil),                // 6: DeleteAgentGroupRequest
+	(*DeleteAgentGroupResponse)(nil),               // 7: DeleteAgentGroupResponse
+	(*GetAgentGroupRequest)(nil),                   // 8: GetAgentGroupRequest
+	(*GetAgentGroupResponse)(nil),                  // 9: GetAgentGroupResponse
+	(*ListAgentGroupsRequest)(nil),                 // 10: ListAgentGroupsRequest
+	(*ListAgentGroupsResponse)(nil),                // 11: ListAgentGroupsResponse
+	(*CreateConfigRequest)(nil),                    // 12: CreateConfigRequest
+	(*CreateConfigResponse)(nil),                   // 13: CreateConfigResponse
+	(*UpdateConfigRequest)(nil),                    // 14: UpdateConfigRequest
+	(*UpdateConfigResponse)(nil),                   // 15: UpdateConfigResponse
+	(*DeleteConfigRequest)(nil),                    // 16: DeleteConfigRequest
+	(*DeleteConfigResponse)(nil),                   // 17: DeleteConfigResponse
+	(*GetConfigRequest)(nil),                       // 18: GetConfigRequest
+	(*GetConfigResponse)(nil),                      // 19: GetConfigResponse
+	(*GetConfigStatusListRequest)(nil),             // 20: GetConfigStatusListRequest
+	(*GetConfigStatusListResponse)(nil),            // 21: GetConfigStatusListResponse
+	(*ListConfigsRequest)(nil),                     // 22: ListConfigsRequest
+	(*ListConfigsResponse)(nil),                    // 23: ListConfigsResponse
+	(*ApplyConfigToAgentGroupRequest)(nil),         // 24: ApplyConfigToAgentGroupRequest
+	(*ApplyConfigToAgentGroupResponse)(nil),        // 25: ApplyConfigToAgentGroupResponse
+	(*RemoveConfigFromAgentGroupRequest)(nil),      // 26: RemoveConfigFromAgentGroupRequest
+	(*RemoveConfigFromAgentGroupResponse)(nil),     // 27: RemoveConfigFromAgentGroupResponse
+	(*GetAppliedConfigsForAgentGroupRequest)(nil),  // 28: GetAppliedConfigsForAgentGroupRequest
+	(*GetAppliedConfigsForAgentGroupResponse)(nil), // 29: GetAppliedConfigsForAgentGroupResponse
+	(*GetAppliedAgentGroupsRequest)(nil),           // 30: GetAppliedAgentGroupsRequest
+	(*GetAppliedAgentGroupsResponse)(nil),          // 31: GetAppliedAgentGroupsResponse
+	(*ListAgentsRequest)(nil),                      // 32: ListAgentsRequest
+	(*ListAgentsResponse)(nil),                     // 33: ListAgentsResponse
+	(*AgentAttributes)(nil),                        // 34: AgentAttributes
+	(ConfigStatus)(0),                              // 35: ConfigStatus
+	(*AgentGroupTag)(nil),                          // 36: AgentGroupTag
+	(*CommonResponse)(nil),                         // 37: CommonResponse
+	(*ConfigDetail)(nil),                           // 38: ConfigDetail
 }
 var file_user_proto_depIdxs = []int32{
-	0,  // 0: configserver.proto.AgentGroup.tags:type_name -> configserver.proto.AgentGroupTag
-	33, // 1: configserver.proto.Agent.attributes:type_name -> configserver.proto.AgentAttributes
-	1,  // 2: configserver.proto.CreateAgentGroupRequest.agent_group:type_name -> configserver.proto.AgentGroup
-	34, // 3: configserver.proto.CreateAgentGroupResponse.code:type_name -> configserver.proto.RespCode
-	1,  // 4: configserver.proto.UpdateAgentGroupRequest.agent_group:type_name -> configserver.proto.AgentGroup
-	34, // 5: configserver.proto.UpdateAgentGroupResponse.code:type_name -> configserver.proto.RespCode
-	34, // 6: configserver.proto.DeleteAgentGroupResponse.code:type_name -> configserver.proto.RespCode
-	34, // 7: configserver.proto.GetAgentGroupResponse.code:type_name -> configserver.proto.RespCode
-	1,  // 8: configserver.proto.GetAgentGroupResponse.agent_group:type_name -> configserver.proto.AgentGroup
-	34, // 9: configserver.proto.ListAgentGroupsResponse.code:type_name -> configserver.proto.RespCode
-	1,  // 10: configserver.proto.ListAgentGroupsResponse.agent_groups:type_name -> configserver.proto.AgentGroup
-	35, // 11: configserver.proto.CreateConfigRequest.config_detail:type_name -> configserver.proto.ConfigDetail
-	34, // 12: configserver.proto.CreateConfigResponse.code:type_name -> configserver.proto.RespCode
-	35, // 13: configserver.proto.UpdateConfigRequest.config_detail:type_name -> configserver.proto.ConfigDetail
-	34, // 14: configserver.proto.UpdateConfigResponse.code:type_name -> configserver.proto.RespCode
-	34, // 15: configserver.proto.DeleteConfigResponse.code:type_name -> configserver.proto.RespCode
-	34, // 16: configserver.proto.GetConfigResponse.code:type_name -> configserver.proto.RespCode
-	35, // 17: configserver.proto.GetConfigResponse.config_detail:type_name -> configserver.proto.ConfigDetail
-	34, // 18: configserver.proto.ListConfigsResponse.code:type_name -> configserver.proto.RespCode
-	35, // 19: configserver.proto.ListConfigsResponse.config_details:type_name -> configserver.proto.ConfigDetail
-	34, // 20: configserver.proto.ApplyConfigToAgentGroupResponse.code:type_name -> configserver.proto.RespCode
-	34, // 21: configserver.proto.RemoveConfigFromAgentGroupResponse.code:type_name -> configserver.proto.RespCode
-	34, // 22: configserver.proto.GetAppliedConfigsForAgentGroupResponse.code:type_name -> configserver.proto.RespCode
-	34, // 23: configserver.proto.GetAppliedAgentGroupsResponse.code:type_name -> configserver.proto.RespCode
-	34, // 24: configserver.proto.ListAgentsResponse.code:type_name -> configserver.proto.RespCode
-	2,  // 25: configserver.proto.ListAgentsResponse.agents:type_name -> configserver.proto.Agent
-	26, // [26:26] is the sub-list for method output_type
-	26, // [26:26] is the sub-list for method input_type
-	26, // [26:26] is the sub-list for extension type_name
-	26, // [26:26] is the sub-list for extension extendee
-	0,  // [0:26] is the sub-list for field type_name
+	34, // 0: Agent.attributes:type_name -> AgentAttributes
+	35, // 1: AgentConfigStatus.status:type_name -> ConfigStatus
+	36, // 2: CreateAgentGroupRequest.agent_group:type_name -> AgentGroupTag
+	37, // 3: CreateAgentGroupResponse.common_response:type_name -> CommonResponse
+	36, // 4: UpdateAgentGroupRequest.agent_group:type_name -> AgentGroupTag
+	37, // 5: UpdateAgentGroupResponse.common_response:type_name -> CommonResponse
+	37, // 6: DeleteAgentGroupResponse.common_response:type_name -> CommonResponse
+	37, // 7: GetAgentGroupResponse.common_response:type_name -> CommonResponse
+	36, // 8: GetAgentGroupResponse.agent_group:type_name -> AgentGroupTag
+	37, // 9: ListAgentGroupsResponse.common_response:type_name -> CommonResponse
+	36, // 10: ListAgentGroupsResponse.agent_groups:type_name -> AgentGroupTag
+	38, // 11: CreateConfigRequest.config_detail:type_name -> ConfigDetail
+	37, // 12: CreateConfigResponse.common_response:type_name -> CommonResponse
+	38, // 13: UpdateConfigRequest.config_detail:type_name -> ConfigDetail
+	37, // 14: UpdateConfigResponse.common_response:type_name -> CommonResponse
+	37, // 15: DeleteConfigResponse.common_response:type_name -> CommonResponse
+	37, // 16: GetConfigResponse.common_response:type_name -> CommonResponse
+	38, // 17: GetConfigResponse.config_detail:type_name -> ConfigDetail
+	37, // 18: GetConfigStatusListResponse.common_response:type_name -> CommonResponse
+	1,  // 19: GetConfigStatusListResponse.agent_config_status:type_name -> AgentConfigStatus
+	37, // 20: ListConfigsResponse.common_response:type_name -> CommonResponse
+	38, // 21: ListConfigsResponse.config_details:type_name -> ConfigDetail
+	37, // 22: ApplyConfigToAgentGroupResponse.common_response:type_name -> CommonResponse
+	37, // 23: RemoveConfigFromAgentGroupResponse.common_response:type_name -> CommonResponse
+	37, // 24: GetAppliedConfigsForAgentGroupResponse.common_response:type_name -> CommonResponse
+	37, // 25: GetAppliedAgentGroupsResponse.common_response:type_name -> CommonResponse
+	37, // 26: ListAgentsResponse.common_response:type_name -> CommonResponse
+	0,  // 27: ListAgentsResponse.agents:type_name -> Agent
+	28, // [28:28] is the sub-list for method output_type
+	28, // [28:28] is the sub-list for method input_type
+	28, // [28:28] is the sub-list for extension type_name
+	28, // [28:28] is the sub-list for extension extendee
+	0,  // [0:28] is the sub-list for field type_name
 }
 
 func init() { file_user_proto_init() }
@@ -2438,20 +2377,8 @@ func file_user_proto_init() {
 	}
 	file_agent_proto_init()
 	if !protoimpl.UnsafeEnabled {
-		file_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*AgentGroupTag); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*AgentGroup); i {
+		file_user_proto_msgTypes[0].Exporter = func(v any, i int) any {
+			switch v := v.(*Agent); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2462,8 +2389,8 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Agent); i {
+		file_user_proto_msgTypes[1].Exporter = func(v any, i int) any {
+			switch v := v.(*AgentConfigStatus); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2474,7 +2401,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[2].Exporter = func(v any, i int) any {
 			switch v := v.(*CreateAgentGroupRequest); i {
 			case 0:
 				return &v.state
@@ -2486,7 +2413,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[3].Exporter = func(v any, i int) any {
 			switch v := v.(*CreateAgentGroupResponse); i {
 			case 0:
 				return &v.state
@@ -2498,7 +2425,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[4].Exporter = func(v any, i int) any {
 			switch v := v.(*UpdateAgentGroupRequest); i {
 			case 0:
 				return &v.state
@@ -2510,7 +2437,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[5].Exporter = func(v any, i int) any {
 			switch v := v.(*UpdateAgentGroupResponse); i {
 			case 0:
 				return &v.state
@@ -2522,7 +2449,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[6].Exporter = func(v any, i int) any {
 			switch v := v.(*DeleteAgentGroupRequest); i {
 			case 0:
 				return &v.state
@@ -2534,7 +2461,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[7].Exporter = func(v any, i int) any {
 			switch v := v.(*DeleteAgentGroupResponse); i {
 			case 0:
 				return &v.state
@@ -2546,7 +2473,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[8].Exporter = func(v any, i int) any {
 			switch v := v.(*GetAgentGroupRequest); i {
 			case 0:
 				return &v.state
@@ -2558,7 +2485,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[9].Exporter = func(v any, i int) any {
 			switch v := v.(*GetAgentGroupResponse); i {
 			case 0:
 				return &v.state
@@ -2570,7 +2497,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[10].Exporter = func(v any, i int) any {
 			switch v := v.(*ListAgentGroupsRequest); i {
 			case 0:
 				return &v.state
@@ -2582,7 +2509,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[11].Exporter = func(v any, i int) any {
 			switch v := v.(*ListAgentGroupsResponse); i {
 			case 0:
 				return &v.state
@@ -2594,7 +2521,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[12].Exporter = func(v any, i int) any {
 			switch v := v.(*CreateConfigRequest); i {
 			case 0:
 				return &v.state
@@ -2606,7 +2533,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[13].Exporter = func(v any, i int) any {
 			switch v := v.(*CreateConfigResponse); i {
 			case 0:
 				return &v.state
@@ -2618,7 +2545,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[14].Exporter = func(v any, i int) any {
 			switch v := v.(*UpdateConfigRequest); i {
 			case 0:
 				return &v.state
@@ -2630,7 +2557,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[15].Exporter = func(v any, i int) any {
 			switch v := v.(*UpdateConfigResponse); i {
 			case 0:
 				return &v.state
@@ -2642,7 +2569,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[16].Exporter = func(v any, i int) any {
 			switch v := v.(*DeleteConfigRequest); i {
 			case 0:
 				return &v.state
@@ -2654,7 +2581,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[17].Exporter = func(v any, i int) any {
 			switch v := v.(*DeleteConfigResponse); i {
 			case 0:
 				return &v.state
@@ -2666,7 +2593,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[18].Exporter = func(v any, i int) any {
 			switch v := v.(*GetConfigRequest); i {
 			case 0:
 				return &v.state
@@ -2678,7 +2605,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[19].Exporter = func(v any, i int) any {
 			switch v := v.(*GetConfigResponse); i {
 			case 0:
 				return &v.state
@@ -2690,7 +2617,31 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[20].Exporter = func(v any, i int) any {
+			switch v := v.(*GetConfigStatusListRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[21].Exporter = func(v any, i int) any {
+			switch v := v.(*GetConfigStatusListResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[22].Exporter = func(v any, i int) any {
 			switch v := v.(*ListConfigsRequest); i {
 			case 0:
 				return &v.state
@@ -2702,7 +2653,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[23].Exporter = func(v any, i int) any {
 			switch v := v.(*ListConfigsResponse); i {
 			case 0:
 				return &v.state
@@ -2714,7 +2665,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[24].Exporter = func(v any, i int) any {
 			switch v := v.(*ApplyConfigToAgentGroupRequest); i {
 			case 0:
 				return &v.state
@@ -2726,7 +2677,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[25].Exporter = func(v any, i int) any {
 			switch v := v.(*ApplyConfigToAgentGroupResponse); i {
 			case 0:
 				return &v.state
@@ -2738,7 +2689,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[26].Exporter = func(v any, i int) any {
 			switch v := v.(*RemoveConfigFromAgentGroupRequest); i {
 			case 0:
 				return &v.state
@@ -2750,7 +2701,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[27].Exporter = func(v any, i int) any {
 			switch v := v.(*RemoveConfigFromAgentGroupResponse); i {
 			case 0:
 				return &v.state
@@ -2762,7 +2713,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[28].Exporter = func(v any, i int) any {
 			switch v := v.(*GetAppliedConfigsForAgentGroupRequest); i {
 			case 0:
 				return &v.state
@@ -2774,7 +2725,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[29].Exporter = func(v any, i int) any {
 			switch v := v.(*GetAppliedConfigsForAgentGroupResponse); i {
 			case 0:
 				return &v.state
@@ -2786,7 +2737,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[30].Exporter = func(v any, i int) any {
 			switch v := v.(*GetAppliedAgentGroupsRequest); i {
 			case 0:
 				return &v.state
@@ -2798,7 +2749,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[31].Exporter = func(v any, i int) any {
 			switch v := v.(*GetAppliedAgentGroupsResponse); i {
 			case 0:
 				return &v.state
@@ -2810,7 +2761,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[32].Exporter = func(v any, i int) any {
 			switch v := v.(*ListAgentsRequest); i {
 			case 0:
 				return &v.state
@@ -2822,7 +2773,7 @@ func file_user_proto_init() {
 				return nil
 			}
 		}
-		file_user_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
+		file_user_proto_msgTypes[33].Exporter = func(v any, i int) any {
 			switch v := v.(*ListAgentsResponse); i {
 			case 0:
 				return &v.state
@@ -2841,7 +2792,7 @@ func file_user_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_user_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   33,
+			NumMessages:   34,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
diff --git a/config_server/service/internal/repository/agent.go b/config_server/service/internal/repository/agent.go
new file mode 100644
index 0000000000..0bdf10a31b
--- /dev/null
+++ b/config_server/service/internal/repository/agent.go
@@ -0,0 +1,89 @@
+package repository
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/entity"
+	"config-server/internal/store"
+	"gorm.io/gorm"
+)
+
+var s = store.S
+
+func GetAgentByiId(instanceId string) *entity.Agent {
+	var agentInfo = new(entity.Agent)
+	row := s.Db.Where("instance_id=?", instanceId).Find(agentInfo).RowsAffected
+	if row == 1 {
+		return agentInfo
+	}
+	return nil
+}
+
+func GetAllAgents(containPipelineConfigs bool, containInstanceConfigs bool) []entity.Agent {
+	var agentInfoList []entity.Agent
+	tx := s.Db
+	if containPipelineConfigs {
+		tx.Preload("PipelineConfigs")
+	}
+	if containInstanceConfigs {
+		tx.Preload("InstanceConfigs")
+	}
+	tx.Find(&agentInfoList)
+	return agentInfoList
+}
+
+func RemoveAgentById(instanceId string) error {
+	var tx *gorm.DB
+
+	tx = s.Db.Where("instance_id=?", instanceId).Delete(&entity.Agent{})
+	if tx.RowsAffected != 1 {
+		return common.ServerErrorWithMsg("Agent failed to delete record %s", instanceId)
+	}
+	s.Db.Where("agent_instance_id=?", instanceId).Delete(&entity.AgentPipelineConfig{})
+	s.Db.Where("agent_instance_id=?", instanceId).Delete(&entity.AgentInstanceConfig{})
+	return nil
+}
+
+func UpdateAgentById(agent *entity.Agent, filed ...string) error {
+	if filed == nil {
+		row := s.Db.Model(agent).Updates(*agent).RowsAffected
+		if row != 1 {
+			return common.ServerErrorWithMsg("update agent error")
+		}
+	}
+	row := s.Db.Model(agent).Select(filed).Updates(*agent).RowsAffected
+	if row != 1 {
+		return common.ServerErrorWithMsg("update agent filed error")
+	}
+	return nil
+}
+
+func CreateOrUpdateAgentBasicInfo(conflictColumnNames []string, agent ...*entity.Agent) error {
+	return createOrUpdateEntities(conflictColumnNames, nil, agent...)
+}
+
+func ListAgentsByGroupName(groupName string) ([]*entity.Agent, error) {
+	agentGroup := entity.AgentGroup{}
+	err := s.Db.Preload("Agents").Where("name=?", groupName).Find(&agentGroup).Error
+	if err != nil {
+		return nil, err
+	}
+	return agentGroup.Agents, nil
+}
+
+func GetPipelineConfigStatusList(instanceId string) ([]*entity.AgentPipelineConfig, error) {
+	configs := make([]*entity.AgentPipelineConfig, 0)
+	err := s.Db.Where("agent_instance_id=?", instanceId).Find(&configs).Error
+	if err != nil {
+		return nil, err
+	}
+	return configs, err
+}
+
+func GetInstanceConfigStatusList(instanceId string) ([]*entity.AgentInstanceConfig, error) {
+	configs := make([]*entity.AgentInstanceConfig, 0)
+	err := s.Db.Where("agent_instance_id=?", instanceId).Find(&configs).Error
+	if err != nil {
+		return nil, err
+	}
+	return configs, err
+}
diff --git a/config_server/service/internal/repository/agent_group.go b/config_server/service/internal/repository/agent_group.go
new file mode 100644
index 0000000000..cebbe95551
--- /dev/null
+++ b/config_server/service/internal/repository/agent_group.go
@@ -0,0 +1,90 @@
+package repository
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/entity"
+)
+
+func CreateAgentGroup(group *entity.AgentGroup) error {
+	row := s.Db.Create(group).RowsAffected
+	if row != 1 {
+		return common.ServerErrorWithMsg("create agentGroup(%s) error", group.Name)
+	}
+	return nil
+}
+
+func UpdateAgentGroup(group *entity.AgentGroup) error {
+	err := s.Db.Save(group).Error
+	return err
+}
+
+func DeleteAgentGroup(name string) error {
+	row := s.Db.Where("name=?", name).Delete(&entity.AgentGroup{}).RowsAffected
+	if row != 1 {
+		return common.ServerErrorWithMsg("delete agentGroup(name=%s) error", name)
+	}
+	return nil
+}
+
+func GetAgentGroupDetail(name string, containPipelineConfigs bool, containInstanceConfigs bool) (*entity.AgentGroup, error) {
+	agentGroup := &entity.AgentGroup{}
+	tx := s.Db.Where("name=?", name)
+	if containPipelineConfigs {
+		tx.Preload("PipelineConfigs")
+	}
+	if containInstanceConfigs {
+		tx.Preload("InstanceConfigs")
+	}
+	row := tx.Find(agentGroup).RowsAffected
+	if row != 1 {
+		return nil, common.ServerErrorWithMsg("get agentGroup(name=%s) error", name)
+	}
+	return agentGroup, nil
+}
+
+func GetAllAgentGroupDetail(containAgents bool, containPipelineConfigs bool, containInstanceConfigs bool) ([]*entity.AgentGroup, error) {
+	agentGroups := make([]*entity.AgentGroup, 0)
+	tx := s.Db.Where("1=1")
+	if containAgents {
+		tx.Preload("Agents")
+	}
+	if containPipelineConfigs {
+		tx.Preload("PipelineConfigs")
+	}
+	if containInstanceConfigs {
+		tx.Preload("InstanceConfigs")
+	}
+	err := tx.Find(&agentGroups).Error
+	return agentGroups, err
+}
+
+func GetAllAgentGroup() ([]*entity.AgentGroup, error) {
+	agentGroups := make([]*entity.AgentGroup, 0)
+	err := s.Db.Find(&agentGroups).Error
+	return agentGroups, err
+}
+
+func GetAppliedAgentGroupForPipelineConfigName(configName string) ([]string, error) {
+	pipelineConfig := &entity.PipelineConfig{}
+	row := s.Db.Preload("AgentGroups").Where("name=?", configName).Find(&pipelineConfig).RowsAffected
+	if row != 1 {
+		return nil, common.ServerErrorWithMsg("can not find name=%s pipelineConfig")
+	}
+	groupNames := make([]string, 0)
+	for _, group := range pipelineConfig.AgentGroups {
+		groupNames = append(groupNames, group.Name)
+	}
+	return groupNames, nil
+}
+func GetAppliedAgentGroupForInstanceConfigName(configName string) ([]string, error) {
+	instanceConfig := &entity.InstanceConfig{}
+	row := s.Db.Preload("AgentGroups").Where("name=?", configName).Find(&instanceConfig).RowsAffected
+	if row != 1 {
+		return nil, common.ServerErrorWithMsg("can not find name=%s pipelineConfig")
+	}
+	groupNames := make([]string, 0)
+	for _, group := range instanceConfig.AgentGroups {
+		groupNames = append(groupNames, group.Name)
+	}
+	return groupNames, nil
+}
diff --git a/config_server/service/internal/repository/base.go b/config_server/service/internal/repository/base.go
new file mode 100644
index 0000000000..9d69bd6d49
--- /dev/null
+++ b/config_server/service/internal/repository/base.go
@@ -0,0 +1,44 @@
+package repository
+
+import (
+	"config-server/internal/common"
+	"gorm.io/gorm/clause"
+)
+
+func generateClauseColumn(names ...string) []clause.Column {
+	if names == nil {
+		return nil
+	}
+	arr := make([]clause.Column, 0)
+	for _, name := range names {
+		arr = append(arr, clause.Column{
+			Name: name,
+		})
+	}
+	return arr
+}
+
+func createOrUpdateEntities[T any](conflictColumnNames []string, assignmentColumns []string, entities ...T) error {
+	if conflictColumnNames == nil {
+		return common.ServerErrorWithMsg("conflictColumnNames could not be null")
+	}
+	if entities == nil || len(entities) == 0 {
+		return nil
+	}
+
+	//如果原样插入,即数据没有任何变化,RowsAffected返回的值是0,所以这里只能用error来判断是否发生插入或更新异常
+	columns := generateClauseColumn(conflictColumnNames...)
+	if assignmentColumns == nil {
+		err := s.Db.Clauses(clause.OnConflict{
+			Columns:   columns,
+			UpdateAll: true,
+		}).Create(&entities).Error
+		return common.SystemError(err)
+	}
+
+	err := s.Db.Clauses(clause.OnConflict{
+		Columns:   columns,                                     // 指定冲突的列
+		DoUpdates: clause.AssignmentColumns(assignmentColumns), // 如果冲突发生,更新的列
+	}).Create(&entities).Error
+	return common.SystemError(err)
+}
diff --git a/config_server/service/internal/repository/config.go b/config_server/service/internal/repository/config.go
new file mode 100644
index 0000000000..f96ff2c24a
--- /dev/null
+++ b/config_server/service/internal/repository/config.go
@@ -0,0 +1,44 @@
+package repository
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/entity"
+)
+
+func CreateOrUpdateAgentPipelineConfigs(conflictColumnNames []string, assignmentColumns []string, configs ...*entity.AgentPipelineConfig) error {
+	err := createOrUpdateEntities(conflictColumnNames, assignmentColumns, configs...)
+	return common.SystemError(err)
+}
+
+func CreateOrUpdateAgentInstanceConfigs(conflictColumnNames []string, assignmentColumns []string, configs ...*entity.AgentInstanceConfig) error {
+	err := createOrUpdateEntities(conflictColumnNames, assignmentColumns, configs...)
+	return common.SystemError(err)
+}
+
+func GetPipelineConfigByName(name string) (*entity.PipelineConfig, error) {
+	pipelineConfig := entity.PipelineConfig{}
+	row := s.Db.Where("name=?", name).Find(&pipelineConfig).RowsAffected
+	if row != 1 {
+		return nil, common.ServerErrorWithMsg("pipelineName=%s can not be found", name)
+	}
+	return &pipelineConfig, nil
+}
+
+func GetInstanceConfigByName(name string) (*entity.InstanceConfig, error) {
+	instanceConfig := entity.InstanceConfig{}
+	row := s.Db.Where("name=?", name).Find(&instanceConfig).RowsAffected
+	if row != 1 {
+		return nil, common.ServerErrorWithMsg("instanceName=%s can not be found", name)
+	}
+	return &instanceConfig, nil
+}
+
+func GetPipelineConfigsByAgent(agent *entity.Agent) error {
+	err := s.Db.Preload("PipelineConfigs").Where("instance_id=?", agent.InstanceId).Find(agent).Error
+	return common.SystemError(err)
+}
+
+func GetInstanceConfigsByAgent(agent *entity.Agent) error {
+	err := s.Db.Preload("InstanceConfigs").Where("instance_id=?", agent.InstanceId).Find(agent).Error
+	return common.SystemError(err)
+}
diff --git a/config_server/service/internal/repository/instance_config.go b/config_server/service/internal/repository/instance_config.go
new file mode 100644
index 0000000000..0c54c68fcc
--- /dev/null
+++ b/config_server/service/internal/repository/instance_config.go
@@ -0,0 +1,117 @@
+package repository
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/entity"
+)
+
+func CreateInstanceConfig(config *entity.InstanceConfig) error {
+	row := s.Db.Create(config).RowsAffected
+	if row != 1 {
+		return common.ServerErrorWithMsg("create InstanceConfig(%s) error", config.Name)
+	}
+	return nil
+}
+
+func UpdateInstanceConfig(config *entity.InstanceConfig) error {
+	err := s.Db.Save(config).Error
+	return err
+}
+
+func DeleteInstanceConfig(configName string) error {
+	row := s.Db.Where("name=?", configName).Delete(&entity.InstanceConfig{}).RowsAffected
+	if row != 1 {
+		return common.ServerErrorWithMsg("delete InstanceConfig(name=%s) error", configName)
+	}
+	return nil
+}
+
+func GetInstanceConfig(configName string) (*entity.InstanceConfig, error) {
+	config := &entity.InstanceConfig{}
+	row := s.Db.Where("name=?", configName).Find(config).RowsAffected
+	if row != 1 {
+		return nil, common.ServerErrorWithMsg("get instanceConfig(name=%s) error", configName)
+	}
+	return config, nil
+}
+
+func ListInstanceConfigs() ([]*entity.InstanceConfig, error) {
+	instanceConfigs := make([]*entity.InstanceConfig, 0)
+	err := s.Db.Find(&instanceConfigs).Error
+	return instanceConfigs, err
+}
+
+func CreateInstanceConfigForAgentGroup(groupName string, configName string) error {
+	removeConfig := entity.InstanceConfig{
+		Name: configName,
+	}
+	agentGroup := entity.AgentGroup{
+		Name: groupName,
+	}
+	err := s.Db.Model(&agentGroup).Association("InstanceConfigs").Append(&removeConfig)
+	return common.SystemError(err)
+}
+
+func CreateInstanceConfigForAgent(instanceId string, configName string) error {
+	agentPipelineConfig := entity.AgentPipelineConfig{
+		AgentInstanceId:    instanceId,
+		PipelineConfigName: configName,
+	}
+	err := s.Db.FirstOrCreate(&agentPipelineConfig).Error
+	return err
+}
+
+//func CreateInstanceConfigForAgentInGroup(agentInstanceIds []string, configName string) error {
+//	agentInstanceConfigs := make([]entity.AgentInstanceConfig, 0)
+//	for _, instanceId := range agentInstanceIds {
+//		agentInstanceConfig := entity.AgentInstanceConfig{
+//			AgentInstanceId:    instanceId,
+//			InstanceConfigName: configName,
+//		}
+//		agentInstanceConfigs = append(agentInstanceConfigs, agentInstanceConfig)
+//	}
+//
+//	if len(agentInstanceConfigs) > 0 {
+//		err := s.Db.Create(agentInstanceConfigs).Error
+//		return common.SystemError(err)
+//	}
+//
+//	return nil
+//}
+
+func DeleteInstanceConfigForAgentGroup(groupName string, configName string) error {
+	removeConfig := entity.InstanceConfig{
+		Name: configName,
+	}
+	agentGroup := entity.AgentGroup{
+		Name: groupName,
+	}
+	err := s.Db.Model(&agentGroup).Association("InstanceConfigs").Delete(&removeConfig)
+	return common.SystemError(err)
+}
+
+func DeleteInstanceConfigForAgentInGroup(agentInstanceIds []string, configName string) error {
+	agentInstanceConfigs := make([]entity.AgentInstanceConfig, 0)
+	for _, instanceId := range agentInstanceIds {
+		agentInstanceConfig := entity.AgentInstanceConfig{
+			AgentInstanceId:    instanceId,
+			InstanceConfigName: configName,
+		}
+		agentInstanceConfigs = append(agentInstanceConfigs, agentInstanceConfig)
+	}
+	if len(agentInstanceConfigs) > 0 {
+		err := s.Db.Delete(agentInstanceConfigs).Error
+		return common.SystemError(err)
+	}
+	return nil
+}
+
+func DeleteAllInstanceConfigAndAgent() {
+	s.Db.Exec("TRUNCATE TABLE agent_instance_config")
+}
+
+func ListAgentInstanceConfig() []*entity.AgentInstanceConfig {
+	agentInstanceConfigs := make([]*entity.AgentInstanceConfig, 0)
+	s.Db.Find(&agentInstanceConfigs)
+	return agentInstanceConfigs
+}
diff --git a/config_server/service/internal/repository/pipeline_config.go b/config_server/service/internal/repository/pipeline_config.go
new file mode 100644
index 0000000000..a0001bb8b9
--- /dev/null
+++ b/config_server/service/internal/repository/pipeline_config.go
@@ -0,0 +1,115 @@
+package repository
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/entity"
+)
+
+func CreatePipelineConfig(config *entity.PipelineConfig) error {
+	row := s.Db.Create(config).RowsAffected
+	if row != 1 {
+		return common.ServerErrorWithMsg("create pipelineConfig(%s) error", config.Name)
+	}
+	return nil
+}
+
+func UpdatePipelineConfig(config *entity.PipelineConfig) error {
+	err := s.Db.Save(config).Error
+	return err
+}
+
+func DeletePipelineConfig(configName string) error {
+	row := s.Db.Where("name=?", configName).Delete(&entity.PipelineConfig{}).RowsAffected
+	if row != 1 {
+		return common.ServerErrorWithMsg("delete pipelineConfig(name=%s) error", configName)
+	}
+	return nil
+}
+
+func GetPipelineConfig(configName string) (*entity.PipelineConfig, error) {
+	config := &entity.PipelineConfig{}
+	row := s.Db.Where("name=?", configName).Find(config).RowsAffected
+	if row != 1 {
+		return nil, common.ServerErrorWithMsg("delete pipelineConfig(name=%s) error", configName)
+	}
+	return config, nil
+}
+
+func ListPipelineConfigs() ([]*entity.PipelineConfig, error) {
+	pipelineConfigs := make([]*entity.PipelineConfig, 0)
+	err := s.Db.Find(&pipelineConfigs).Error
+	return pipelineConfigs, err
+}
+
+func CreatePipelineConfigForAgentGroup(groupName string, configName string) error {
+	removeConfig := entity.PipelineConfig{
+		Name: configName,
+	}
+	agentGroup := entity.AgentGroup{
+		Name: groupName,
+	}
+	err := s.Db.Model(&agentGroup).Association("PipelineConfigs").Append(&removeConfig)
+	return common.SystemError(err)
+}
+
+func CreatePipelineConfigForAgent(instanceId string, configName string) error {
+	agentPipelineConfig := entity.AgentPipelineConfig{
+		AgentInstanceId:    instanceId,
+		PipelineConfigName: configName,
+	}
+	err := s.Db.FirstOrCreate(&agentPipelineConfig).Error
+	return err
+}
+
+//func CreatePipelineConfigForAgentInGroup(agentInstanceIds []string, configName string) error {
+//	agentPipelineConfigs := make([]entity.AgentPipelineConfig, 0)
+//	for _, instanceId := range agentInstanceIds {
+//		agentPipelineConfig := entity.AgentPipelineConfig{
+//			AgentInstanceId:    instanceId,
+//			PipelineConfigName: configName,
+//		}
+//		agentPipelineConfigs = append(agentPipelineConfigs, agentPipelineConfig)
+//	}
+//	if len(agentPipelineConfigs) > 0 {
+//		err := s.Db.Create(&agentPipelineConfigs).Error
+//		return common.SystemError(err)
+//	}
+//	return nil
+//}
+
+func DeletePipelineConfigForAgentGroup(groupName string, configName string) error {
+	removeConfig := entity.PipelineConfig{
+		Name: configName,
+	}
+	agentGroup := entity.AgentGroup{
+		Name: groupName,
+	}
+	err := s.Db.Model(&agentGroup).Association("PipelineConfigs").Delete(&removeConfig)
+	return common.SystemError(err)
+}
+
+func DeletePipelineConfigForAgentInGroup(agentInstanceIds []string, configName string) error {
+	agentPipelineConfigs := make([]entity.AgentPipelineConfig, 0)
+	for _, instanceId := range agentInstanceIds {
+		agentPipelineConfig := entity.AgentPipelineConfig{
+			AgentInstanceId:    instanceId,
+			PipelineConfigName: configName,
+		}
+		agentPipelineConfigs = append(agentPipelineConfigs, agentPipelineConfig)
+	}
+	if len(agentPipelineConfigs) > 0 {
+		err := s.Db.Delete(&agentPipelineConfigs).Error
+		return common.SystemError(err)
+	}
+	return nil
+}
+
+func DeleteAllPipelineConfigAndAgent() {
+	s.Db.Exec("TRUNCATE TABLE agent_pipeline_config")
+}
+
+func ListAgentPipelineConfig() []*entity.AgentPipelineConfig {
+	agentPipelineConfigs := make([]*entity.AgentPipelineConfig, 0)
+	s.Db.Find(&agentPipelineConfigs)
+	return agentPipelineConfigs
+}
diff --git a/config_server/service/internal/router/router.go b/config_server/service/internal/router/router.go
new file mode 100644
index 0000000000..2d5ac3d3e0
--- /dev/null
+++ b/config_server/service/internal/router/router.go
@@ -0,0 +1,70 @@
+package router
+
+import (
+	"config-server/internal/handler"
+	"github.com/gin-gonic/gin"
+)
+
+func initUserRouter(router *gin.Engine) {
+	userRouter := router.Group("/User")
+	{
+		userRouter.POST("/CreateAgentGroup", handler.CreateAgentGroup)
+		userRouter.POST("/UpdateAgentGroup", handler.UpdateAgentGroup)
+		userRouter.POST("/DeleteAgentGroup", handler.DeleteAgentGroup)
+		userRouter.POST("/GetAgentGroup", handler.GetAgentGroup)
+		userRouter.POST("/ListAgentGroups", handler.ListAgentGroups)
+		userRouter.POST("/ListAgents", handler.ListAgentsInGroup)
+		userRouter.POST("/GetAppliedPipelineConfigsForAgentGroup", handler.GetAppliedPipelineConfigsForAgentGroup)
+		userRouter.POST("/GetAppliedInstanceConfigsForAgentGroup", handler.GetAppliedInstanceConfigsForAgentGroup)
+
+		userRouter.POST("/CreatePipelineConfig", handler.CreatePipelineConfig)
+		userRouter.POST("/UpdatePipelineConfig", handler.UpdatePipelineConfig)
+		userRouter.POST("/DeletePipelineConfig", handler.DeletePipelineConfig)
+		userRouter.POST("/GetPipelineConfig", handler.GetPipelineConfig)
+		userRouter.POST("/ListPipelineConfigs", handler.ListPipelineConfigs)
+		userRouter.POST("/ApplyPipelineConfigToAgentGroup", handler.ApplyPipelineConfigToAgentGroup)
+		userRouter.POST("/RemovePipelineConfigFromAgentGroup", handler.RemovePipelineConfigFromAgentGroup)
+		userRouter.POST("/GetAppliedAgentGroupsWithPipelineConfig", handler.GetAppliedAgentGroupsWithPipelineConfig)
+		userRouter.POST("/GetPipelineConfigStatusList", handler.GetPipelineConfigStatusList)
+
+		userRouter.POST("/CreateInstanceConfig", handler.CreateInstanceConfig)
+		userRouter.POST("/UpdateInstanceConfig", handler.UpdateInstanceConfig)
+		userRouter.POST("/DeleteInstanceConfig", handler.DeleteInstanceConfig)
+		userRouter.POST("/GetInstanceConfig", handler.GetInstanceConfig)
+		userRouter.POST("/ListInstanceConfigs", handler.ListInstanceConfigs)
+		userRouter.POST("/ApplyInstanceConfigToAgentGroup", handler.ApplyInstanceConfigToAgentGroup)
+		userRouter.POST("/RemoveInstanceConfigFromAgentGroup", handler.RemoveInstanceConfigFromAgentGroup)
+		userRouter.POST("/GetAppliedAgentGroupsWithInstanceConfig", handler.GetAppliedAgentGroupsWithInstanceConfig)
+		userRouter.POST("/GetInstanceConfigStatusList", handler.GetInstanceConfigStatusList)
+	}
+
+}
+
+func initAgentRouter(router *gin.Engine) {
+	agentRouter := router.Group("/Agent")
+	{
+		agentRouter.POST("/Heartbeat", handler.HeartBeat)
+		agentRouter.POST("/FetchPipelineConfig", handler.FetchPipelineConfig)
+		//agent有bug暂时不开启此路由
+		//agentRouter.POST("/FetchProcessConfig", handler.FetchProcessConfig)
+	}
+	handler.CheckAgentExist()
+	handler.AppliedOrRemoveConfigForAgentGroup()
+}
+
+func initTest(router *gin.Engine) {
+	testRouter := router.Group("/Test")
+	{
+		testRouter.GET("", func(c *gin.Context) {
+			c.JSON(200, gin.H{
+				"config-server": "connect success",
+			})
+		})
+	}
+}
+
+func InitAllRouter(router *gin.Engine) {
+	initAgentRouter(router)
+	initUserRouter(router)
+	initTest(router)
+}
diff --git a/config_server/service/internal/router/router_test.go b/config_server/service/internal/router/router_test.go
new file mode 100644
index 0000000000..13382ded05
--- /dev/null
+++ b/config_server/service/internal/router/router_test.go
@@ -0,0 +1,75 @@
+package router
+
+import (
+	"bytes"
+	"config-server/internal/config"
+	"config-server/internal/protov2"
+	"fmt"
+	"google.golang.org/protobuf/proto"
+	"io"
+	"log"
+	"net/http"
+	"testing"
+)
+
+var UserUrlPrefix = fmt.Sprintf("http://%s/User", config.ServerConfigInstance.Address)
+
+const (
+	GET    = "GET"
+	POST   = "POST"
+	DELETE = "DELETE"
+	PUT    = "PUT"
+)
+
+func sendProtobufRequest[T, S proto.Message](url string, methodType string, req T, res S) error {
+
+	// 序列化 Protobuf 消息
+	data, err := proto.Marshal(req)
+	if err != nil {
+		return fmt.Errorf("failed to marshal request: %w", err)
+	}
+
+	// 创建 HTTP 请求
+	httpReq, err := http.NewRequest(methodType, url, bytes.NewReader(data))
+	if err != nil {
+		return fmt.Errorf("failed to create request: %w", err)
+	}
+
+	// 设置请求头
+	httpReq.Header.Set("Content-Type", "application/x-protobuf")
+
+	// 发送请求
+	client := &http.Client{}
+	resp, err := client.Do(httpReq)
+	if err != nil {
+		return fmt.Errorf("failed to send request: %w", err)
+	}
+	defer resp.Body.Close()
+
+	// 读取响应
+	body, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return fmt.Errorf("failed to read response body: %w", err)
+	}
+
+	if err := proto.Unmarshal(body, res); err != nil {
+		return fmt.Errorf("failed to unmarshal response: %w", err)
+	}
+	fmt.Println(res)
+	return nil
+}
+
+func TestListAgents(t *testing.T) {
+	url := fmt.Sprintf("%s/ApplyPipelineConfigToAgentGroup", UserUrlPrefix)
+
+	req := &protov2.ApplyConfigToAgentGroupRequest{}
+	res := &protov2.ApplyConfigToAgentGroupResponse{}
+
+	req.RequestId = []byte("123456")
+	req.GroupName = "nzh"
+	req.ConfigName = "nzh"
+
+	if err := sendProtobufRequest(url, PUT, req, res); err != nil {
+		log.Fatalf("Request failed: %v", err)
+	}
+}
diff --git a/config_server/service/internal/service/agent.go b/config_server/service/internal/service/agent.go
new file mode 100644
index 0000000000..62289a70e5
--- /dev/null
+++ b/config_server/service/internal/service/agent.go
@@ -0,0 +1,174 @@
+package service
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/entity"
+	"config-server/internal/manager"
+	"config-server/internal/manager/flag"
+	proto "config-server/internal/protov2"
+	"config-server/internal/repository"
+	"config-server/internal/utils"
+	"time"
+)
+
+// CheckAgentExist  确认心跳,失败则下线对应的实例
+func CheckAgentExist(timeLimit int64) {
+	utils.TimedTask(timeLimit, func(timeLimitParam int64) {
+		timeLimitNano := timeLimitParam * int64(time.Second)
+		utils.ParallelProcessSlice[entity.Agent](manager.GetAllAgentsBasicInfo(),
+			func(_ int, agentInfo entity.Agent) {
+				manager.RemoveAgentNow(&agentInfo, timeLimitNano)
+			})
+	})
+}
+
+func HeartBeat(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	instanceId := req.InstanceId
+	if instanceId == nil {
+		return common.ValidateErrorWithMsg("required field instanceId could not be null")
+	}
+
+	var err error
+	sequenceNum := req.SequenceNum
+
+	rationality := manager.JudgeSequenceNumRationality(instanceId, sequenceNum)
+
+	//假设数据库保存的sequenceNum=3,agent给的是10,
+	//如果在判断rationality=false立即return,数据库中保存的一直是3,agent一直重传全部状态
+	if !rationality {
+		res.Flags = res.Flags | uint64(flag.ResponseMap[flag.ReportFullState].Code)
+	}
+
+	currentHeatBeatTime := time.Now().UnixNano()
+	agent := entity.ParseHeartBeatRequest2BasicAgent(req, currentHeatBeatTime)
+	agent.Tags = manager.AddDefaultAgentGroup(agent.Tags)
+
+	//Regardless of whether sequenceN is legal or not, we should keep the basic information of the agent (sequenceNum, instanceId, capabilities, flags, etc.)
+	err = manager.CreateOrUpdateAgentBasicInfo(agent)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	//如果req未设置fullState,agent会不会上传其他的configStatus
+	err = flag.HandleRequestFlags(req, res)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	err = flag.HandleResponseFlags(req, res)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	return nil
+}
+
+func FetchPipelineConfigDetail(req *proto.FetchConfigRequest, res *proto.FetchConfigResponse) error {
+	instanceId := req.InstanceId
+	if instanceId == nil {
+		return common.ValidateErrorWithMsg("required field instanceId could not be null")
+	}
+
+	var err error
+	strInstanceId := string(instanceId)
+
+	//创建或更新pipelineConfig的status and message
+	agentPipelineConfigs := make([]*entity.AgentPipelineConfig, 0)
+	for _, reqConfig := range req.ReqConfigs {
+		agentPipelineConfig := entity.ParseProtoConfigInfo2AgentPipelineConfig(strInstanceId, reqConfig)
+		agentPipelineConfigs = append(agentPipelineConfigs, agentPipelineConfig)
+	}
+
+	err = manager.CreateOrUpdateAgentPipelineConfigs(agentPipelineConfigs)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	//返回pipelineConfigDetail
+	pipelineConfigUpdates, err := manager.GetPipelineConfigs(strInstanceId, true)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	res.ConfigDetails = pipelineConfigUpdates
+	return nil
+}
+
+func FetchInstanceConfigDetail(req *proto.FetchConfigRequest, res *proto.FetchConfigResponse) error {
+	instanceId := req.InstanceId
+	if instanceId == nil {
+		return common.ValidateErrorWithMsg("required field instanceId could not be null")
+	}
+
+	var err error
+	strInstanceId := string(instanceId)
+
+	agentInstanceConfigs := make([]*entity.AgentInstanceConfig, 0)
+	for _, reqConfig := range req.ReqConfigs {
+		agentInstanceConfig := entity.ParseProtoConfigInfo2AgentInstanceConfig(strInstanceId, reqConfig)
+		agentInstanceConfigs = append(agentInstanceConfigs, agentInstanceConfig)
+	}
+
+	err = manager.CreateOrUpdateAgentInstanceConfigs(agentInstanceConfigs)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	//获取对应的configDetails
+	instanceConfigUpdates, err := manager.GetInstanceConfigs(strInstanceId, true)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	res.ConfigDetails = instanceConfigUpdates
+	return nil
+}
+
+func ListAgentsInGroup(req *proto.ListAgentsRequest, res *proto.ListAgentsResponse) error {
+	groupName := req.GroupName
+	if groupName == "" {
+		return common.ValidateErrorWithMsg("required fields groupName could not be null")
+	}
+	agents, err := repository.ListAgentsByGroupName(groupName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	protoAgents := make([]*proto.Agent, 0)
+	for _, agent := range agents {
+		protoAgents = append(protoAgents, (*agent).Parse2Proto())
+	}
+	res.Agents = protoAgents
+	return nil
+}
+
+func GetPipelineConfigStatusList(req *proto.GetConfigStatusListRequest, res *proto.GetConfigStatusListResponse) error {
+	instanceId := req.InstanceId
+	if instanceId == nil {
+		return common.ValidateErrorWithMsg("required fields instanceId could not be null")
+	}
+	configs, err := repository.GetPipelineConfigStatusList(string(instanceId))
+	if err != nil {
+		return common.SystemError(err)
+	}
+	agentConfigStatusList := make([]*proto.AgentConfigStatus, 0)
+	for _, config := range configs {
+		agentConfigStatusList = append(agentConfigStatusList, config.Parse2ProtoAgentConfigStatus())
+	}
+	res.AgentConfigStatus = agentConfigStatusList
+	return nil
+}
+
+func GetInstanceConfigStatusList(req *proto.GetConfigStatusListRequest, res *proto.GetConfigStatusListResponse) error {
+	instanceId := req.InstanceId
+	if instanceId == nil {
+		return common.ValidateErrorWithMsg("required fields instanceId could not be null")
+	}
+	configs, err := repository.GetInstanceConfigStatusList(string(instanceId))
+	if err != nil {
+		return common.SystemError(err)
+	}
+	agentConfigStatusList := make([]*proto.AgentConfigStatus, 0)
+	for _, config := range configs {
+		agentConfigStatusList = append(agentConfigStatusList, config.Parse2ProtoAgentConfigStatus())
+	}
+	res.AgentConfigStatus = agentConfigStatusList
+	return nil
+}
diff --git a/config_server/service/internal/service/agent_group.go b/config_server/service/internal/service/agent_group.go
new file mode 100644
index 0000000000..42039717a6
--- /dev/null
+++ b/config_server/service/internal/service/agent_group.go
@@ -0,0 +1,114 @@
+package service
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/entity"
+	"config-server/internal/manager"
+	"config-server/internal/protov2"
+	"config-server/internal/repository"
+	"config-server/internal/utils"
+)
+
+// AppliedOrRemoveConfigForAgentGroup 定期检查在group中的agent与config的关系是否符合group与config的关系
+func AppliedOrRemoveConfigForAgentGroup(timeLimit int64) {
+	utils.TimedTask(timeLimit, func(int64) {
+		agentGroupDetails, err := repository.GetAllAgentGroupDetail(true, true, true)
+		if err != nil {
+			panic(err)
+		}
+		utils.ParallelProcessTask(agentGroupDetails,
+			manager.AppliedOrRemovePipelineConfigForAgentGroup,
+			manager.AppliedOrRemoveInstanceConfigForAgentGroup)
+	})
+}
+
+func CreateAgentGroup(req *protov2.CreateAgentGroupRequest, res *protov2.CreateAgentGroupResponse) error {
+	agentGroup := req.AgentGroup
+	if agentGroup == nil {
+		return common.ValidateErrorWithMsg("required field agentGroup could not be null")
+	}
+	if utils.IsEmptyOrWhitespace(agentGroup.Name) {
+		return common.ValidateErrorWithMsg("required field agentGroupName could not be null")
+	}
+
+	group := entity.ParseProtoAgentGroupTag2AgentGroup(agentGroup)
+	err := repository.CreateAgentGroup(group)
+	return common.SystemError(err)
+}
+
+func UpdateAgentGroup(req *protov2.UpdateAgentGroupRequest, res *protov2.UpdateAgentGroupResponse) error {
+	agentGroup := req.AgentGroup
+	if agentGroup == nil {
+		return common.ValidateErrorWithMsg("required field agentGroup could not be null")
+	}
+	group := entity.ParseProtoAgentGroupTag2AgentGroup(agentGroup)
+	err := repository.UpdateAgentGroup(group)
+	return common.SystemError(err)
+}
+
+func DeleteAgentGroup(req *protov2.DeleteAgentGroupRequest, res *protov2.DeleteAgentGroupResponse) error {
+	agentGroupName := req.GroupName
+	if agentGroupName == "" {
+		return common.ValidateErrorWithMsg("required field groupName could not be null")
+	}
+	if req.GroupName == entity.AgentGroupDefaultValue {
+		return common.ServerErrorWithMsg("%s can not be deleted", entity.AgentGroupDefaultValue)
+	}
+	err := repository.DeleteAgentGroup(agentGroupName)
+	return common.SystemError(err)
+}
+
+func GetAgentGroup(req *protov2.GetAgentGroupRequest, res *protov2.GetAgentGroupResponse) error {
+	agentGroupName := req.GroupName
+	if agentGroupName == "" {
+		return common.ValidateErrorWithMsg("required field groupName could not be null")
+	}
+
+	agentGroup, err := repository.GetAgentGroupDetail(agentGroupName, false, false)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	res.AgentGroup = agentGroup.Parse2ProtoAgentGroupTag()
+	return nil
+}
+
+func ListAgentGroups(req *protov2.ListAgentGroupsRequest, res *protov2.ListAgentGroupsResponse) error {
+	agentGroups, err := repository.GetAllAgentGroup()
+	if err != nil {
+		return common.SystemError(err)
+	}
+	protoAgentGroups := make([]*protov2.AgentGroupTag, 0)
+	for _, agentGroup := range agentGroups {
+		protoAgentGroups = append(protoAgentGroups, agentGroup.Parse2ProtoAgentGroupTag())
+	}
+	res.AgentGroups = protoAgentGroups
+	return nil
+}
+
+func GetAppliedAgentGroupsForPipelineConfigName(req *protov2.GetAppliedAgentGroupsRequest, res *protov2.GetAppliedAgentGroupsResponse) error {
+	configName := req.ConfigName
+	if configName == "" {
+		return common.ValidateErrorWithMsg("required fields configName could not be null")
+	}
+
+	groupNames, err := repository.GetAppliedAgentGroupForPipelineConfigName(configName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	res.AgentGroupNames = groupNames
+	return nil
+}
+
+func GetAppliedAgentGroupsForInstanceConfigName(req *protov2.GetAppliedAgentGroupsRequest, res *protov2.GetAppliedAgentGroupsResponse) error {
+	configName := req.ConfigName
+	if configName == "" {
+		return common.ValidateErrorWithMsg("required fields configName could not be null")
+	}
+
+	groupNames, err := repository.GetAppliedAgentGroupForInstanceConfigName(configName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	res.AgentGroupNames = groupNames
+	return nil
+}
diff --git a/config_server/service/internal/service/instance_config.go b/config_server/service/internal/service/instance_config.go
new file mode 100644
index 0000000000..9fa10a5419
--- /dev/null
+++ b/config_server/service/internal/service/instance_config.go
@@ -0,0 +1,149 @@
+package service
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/entity"
+	proto "config-server/internal/protov2"
+	"config-server/internal/repository"
+	"config-server/internal/utils"
+)
+
+func CreateInstanceConfig(req *proto.CreateConfigRequest, res *proto.CreateConfigResponse) error {
+	configDetail := req.ConfigDetail
+	if utils.IsEmptyOrWhitespace(configDetail.Name) {
+		return common.ValidateErrorWithMsg("required field configName could not be null")
+	}
+
+	if configDetail.Version == 0 {
+		return common.ValidateErrorWithMsg("required field version could not be null")
+	}
+	instanceConfig := entity.ParseProtoInstanceConfig2InstanceConfig(configDetail)
+	err := repository.CreateInstanceConfig(instanceConfig)
+	return common.SystemError(err)
+
+}
+
+func UpdateInstanceConfig(req *proto.UpdateConfigRequest, res *proto.UpdateConfigResponse) error {
+	configDetail := req.ConfigDetail
+	if configDetail.Name == "" {
+		return common.ValidateErrorWithMsg("required field configName could not be null")
+	}
+
+	if configDetail.Version == 0 {
+		return common.ValidateErrorWithMsg("required field version could not be null")
+	}
+	instanceConfig := entity.ParseProtoInstanceConfig2InstanceConfig(configDetail)
+	err := repository.UpdateInstanceConfig(instanceConfig)
+	return common.SystemError(err)
+}
+
+func DeleteInstanceConfig(req *proto.DeleteConfigRequest, res *proto.DeleteConfigResponse) error {
+	configName := req.ConfigName
+	if configName == "" {
+		return common.ValidateErrorWithMsg("required field configName could not be null")
+	}
+	err := repository.DeleteInstanceConfig(configName)
+	return common.SystemError(err)
+}
+
+func GetInstanceConfig(req *proto.GetConfigRequest, res *proto.GetConfigResponse) error {
+	configName := req.ConfigName
+	if configName == "" {
+		return common.ValidateErrorWithMsg("required field configName could not be null")
+	}
+
+	instanceConfig, err := repository.GetInstanceConfig(configName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	if instanceConfig != nil {
+		res.ConfigDetail = instanceConfig.Parse2ProtoInstanceConfigDetail(true)
+	}
+	return common.SystemError(err)
+}
+
+func ListInstanceConfigs(req *proto.ListConfigsRequest, res *proto.ListConfigsResponse) error {
+	instanceConfigs, err := repository.ListInstanceConfigs()
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	for _, instanceConfig := range instanceConfigs {
+		res.ConfigDetails = append(res.ConfigDetails, instanceConfig.Parse2ProtoInstanceConfigDetail(true))
+	}
+	return nil
+}
+
+func ApplyInstanceConfigToAgentGroup(req *proto.ApplyConfigToAgentGroupRequest, res *proto.ApplyConfigToAgentGroupResponse) error {
+	groupName := req.GroupName
+	if groupName == "" {
+		return common.ValidateErrorWithMsg("required fields groupName could not be null")
+	}
+	configName := req.ConfigName
+	if configName == "" {
+		return common.ValidateErrorWithMsg("required fields configName could not be null")
+	}
+
+	var err error
+	err = repository.CreateInstanceConfigForAgentGroup(groupName, configName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	agents, err := repository.ListAgentsByGroupName(groupName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	for _, agent := range agents {
+		err := repository.CreateInstanceConfigForAgent(agent.InstanceId, configName)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func RemoveInstanceConfigFromAgentGroup(req *proto.RemoveConfigFromAgentGroupRequest, res *proto.RemoveConfigFromAgentGroupResponse) error {
+	groupName := req.GroupName
+	if groupName == "" {
+		return common.ValidateErrorWithMsg("required fields groupName could not be null")
+	}
+	configName := req.ConfigName
+
+	err := repository.DeleteInstanceConfigForAgentGroup(groupName, configName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	agents, err := repository.ListAgentsByGroupName(groupName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	agentInstanceIds := make([]string, 0)
+	for _, agent := range agents {
+		agentInstanceIds = append(agentInstanceIds, agent.InstanceId)
+	}
+
+	return repository.DeleteInstanceConfigForAgentInGroup(agentInstanceIds, configName)
+}
+
+func GetAppliedInstanceConfigsForAgentGroup(req *proto.GetAppliedConfigsForAgentGroupRequest, res *proto.GetAppliedConfigsForAgentGroupResponse) error {
+	groupName := req.GroupName
+	if groupName == "" {
+		return common.ValidateErrorWithMsg("required fields groupName could not be null")
+	}
+
+	agentGroupDetail, err := repository.GetAgentGroupDetail(groupName, false, true)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	configNames := make([]string, 0)
+	for _, config := range agentGroupDetail.InstanceConfigs {
+		configNames = append(configNames, config.Name)
+	}
+
+	res.ConfigNames = configNames
+	return nil
+}
diff --git a/config_server/service/internal/service/pipeline_config.go b/config_server/service/internal/service/pipeline_config.go
new file mode 100644
index 0000000000..dca5b8a686
--- /dev/null
+++ b/config_server/service/internal/service/pipeline_config.go
@@ -0,0 +1,153 @@
+package service
+
+import (
+	"config-server/internal/common"
+	"config-server/internal/entity"
+	proto "config-server/internal/protov2"
+	"config-server/internal/repository"
+	"config-server/internal/utils"
+)
+
+func CreatePipelineConfig(req *proto.CreateConfigRequest, res *proto.CreateConfigResponse) error {
+	configDetail := req.ConfigDetail
+	if utils.IsEmptyOrWhitespace(configDetail.Name) {
+		return common.ValidateErrorWithMsg("required field configName could not be null")
+	}
+
+	if configDetail.Version == 0 {
+		return common.ValidateErrorWithMsg("required field version could not be null")
+	}
+
+	pipelineConfig := entity.ParseProtoPipelineConfig2PipelineConfig(configDetail)
+	err := repository.CreatePipelineConfig(pipelineConfig)
+	return common.SystemError(err)
+
+}
+
+func UpdatePipelineConfig(req *proto.UpdateConfigRequest, res *proto.UpdateConfigResponse) error {
+	configDetail := req.ConfigDetail
+	if configDetail.Name == "" {
+		return common.ValidateErrorWithMsg("required field configName could not be null")
+	}
+
+	if configDetail.Version == 0 {
+		return common.ValidateErrorWithMsg("required field version could not be null")
+	}
+	pipelineConfig := entity.ParseProtoPipelineConfig2PipelineConfig(configDetail)
+	err := repository.UpdatePipelineConfig(pipelineConfig)
+	return common.SystemError(err)
+}
+
+func DeletePipelineConfig(req *proto.DeleteConfigRequest, res *proto.DeleteConfigResponse) error {
+	configName := req.ConfigName
+	if configName == "" {
+		return common.ValidateErrorWithMsg("required field configName could not be null")
+	}
+	err := repository.DeletePipelineConfig(configName)
+	return common.SystemError(err)
+}
+
+func GetPipelineConfig(req *proto.GetConfigRequest, res *proto.GetConfigResponse) error {
+	configName := req.ConfigName
+	if configName == "" {
+		return common.ValidateErrorWithMsg("required field configName could not be null")
+	}
+
+	pipelineConfig, err := repository.GetPipelineConfig(configName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	if pipelineConfig != nil {
+		res.ConfigDetail = pipelineConfig.Parse2ProtoPipelineConfigDetail(true)
+	}
+	return common.SystemError(err)
+}
+
+func ListPipelineConfigs(req *proto.ListConfigsRequest, res *proto.ListConfigsResponse) error {
+	pipelineConfigs, err := repository.ListPipelineConfigs()
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	for _, pipelineConfig := range pipelineConfigs {
+		res.ConfigDetails = append(res.ConfigDetails, pipelineConfig.Parse2ProtoPipelineConfigDetail(true))
+	}
+	return nil
+}
+
+func ApplyPipelineConfigToAgentGroup(req *proto.ApplyConfigToAgentGroupRequest, res *proto.ApplyConfigToAgentGroupResponse) error {
+	groupName := req.GroupName
+	if groupName == "" {
+		return common.ValidateErrorWithMsg("required fields groupName could not be null")
+	}
+	configName := req.ConfigName
+	if configName == "" {
+		return common.ValidateErrorWithMsg("required fields configName could not be null")
+	}
+
+	var err error
+	err = repository.CreatePipelineConfigForAgentGroup(groupName, configName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	agents, err := repository.ListAgentsByGroupName(groupName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	for _, agent := range agents {
+		err := repository.CreatePipelineConfigForAgent(agent.InstanceId, configName)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func RemovePipelineConfigFromAgentGroup(req *proto.RemoveConfigFromAgentGroupRequest, res *proto.RemoveConfigFromAgentGroupResponse) error {
+	groupName := req.GroupName
+	if groupName == "" {
+		return common.ValidateErrorWithMsg("required fields groupName could not be null")
+	}
+	configName := req.ConfigName
+	if configName == "" {
+		return common.ValidateErrorWithMsg("required fields configName could not be null")
+	}
+
+	err := repository.DeletePipelineConfigForAgentGroup(groupName, configName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	agents, err := repository.ListAgentsByGroupName(groupName)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	agentInstanceIds := make([]string, 0)
+	for _, agent := range agents {
+		agentInstanceIds = append(agentInstanceIds, agent.InstanceId)
+	}
+
+	return repository.DeletePipelineConfigForAgentInGroup(agentInstanceIds, configName)
+}
+
+func GetAppliedPipelineConfigsForAgentGroup(req *proto.GetAppliedConfigsForAgentGroupRequest, res *proto.GetAppliedConfigsForAgentGroupResponse) error {
+	groupName := req.GroupName
+	if groupName == "" {
+		return common.ValidateErrorWithMsg("required fields groupName could not be null")
+	}
+
+	agentGroupDetail, err := repository.GetAgentGroupDetail(groupName, true, false)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	configNames := make([]string, 0)
+	for _, config := range agentGroupDetail.PipelineConfigs {
+		configNames = append(configNames, config.Name)
+	}
+
+	res.ConfigNames = configNames
+	return nil
+}
diff --git a/config_server/service/internal/store/gorm.go b/config_server/service/internal/store/gorm.go
new file mode 100644
index 0000000000..1609d69db5
--- /dev/null
+++ b/config_server/service/internal/store/gorm.go
@@ -0,0 +1,171 @@
+package store
+
+import (
+	"config-server/internal/config"
+	"config-server/internal/entity"
+	"fmt"
+	"gorm.io/gorm"
+	"log"
+)
+
+var S = new(GormStore)
+
+type GormStore struct {
+	Config *config.GormConfig
+	Db     *gorm.DB
+}
+
+var tableList = []any{
+	&entity.InstanceConfig{},
+	&entity.PipelineConfig{},
+	&entity.AgentGroup{},
+	&entity.Agent{},
+	&entity.AgentPipelineConfig{},
+	&entity.AgentInstanceConfig{},
+}
+
+var tableNameList = []string{
+	entity.AgentGroup{}.TableName(),
+	entity.AgentAgentGroupTable,
+
+	entity.AgentGroupInstanceConfigTable,
+	entity.AgentGroupPipelineConfigTable,
+
+	entity.Agent{}.TableName(),
+
+	entity.InstanceConfig{}.TableName(),
+	entity.PipelineConfig{}.TableName(),
+	entity.AgentPipelineConfig{}.TableName(),
+	entity.AgentInstanceConfig{}.TableName(),
+}
+
+func (s *GormStore) Connect2Db() error {
+	var err error
+	var dialect gorm.Dialector
+	s.Config, dialect, err = config.Connect2Db()
+	if err != nil {
+		return err
+	}
+	log.Printf("test connect database type=%s host=%s:%d ...",
+		s.Config.Type, s.Config.Host, s.Config.Port)
+	s.Db, err = gorm.Open(dialect)
+	if err != nil {
+		return err
+	}
+	dbName := s.Config.DbName
+	log.Printf("create database %s ...", dbName)
+	err = s.Db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", dbName)).Error
+	if err != nil {
+		return err
+	}
+	log.Printf("create database %s success ...", dbName)
+	log.Printf("check %s ...", dbName)
+	err = s.Db.Exec(fmt.Sprintf("USE %s", s.Config.DbName)).Error
+	if err != nil {
+		return err
+	}
+	log.Printf("check %s success", dbName)
+	return nil
+}
+
+func (s *GormStore) Connect2SpecifiedDb() error {
+	var err error
+	var dialect gorm.Dialector
+	s.Config, dialect, err = config.Connect2SpecifiedDb()
+	if err != nil {
+		return err
+	}
+	dbName := s.Config.DbName
+	log.Printf("test connect database type=%s host=%s:%d dbName=%s ...",
+		s.Config.Type, s.Config.Host, s.Config.Port, dbName)
+	s.Db, err = gorm.Open(dialect)
+	if err != nil {
+		return err
+	}
+	log.Printf("sucess connect database type=%s host=%s:%d dbName=%s ...",
+		s.Config.Type, s.Config.Host, s.Config.Port, dbName)
+	return nil
+}
+
+func (s *GormStore) Close() error {
+	db, err := s.Db.DB()
+	if err != nil {
+		return err
+	}
+	return db.Close()
+}
+
+func (s *GormStore) CreateTables() error {
+	//AgentPipeConfig和AgentInstanceConfig要额外autoMigrate是因为他们有多余的属性
+	log.Printf("create tables ...")
+	err := s.Db.AutoMigrate(tableList...)
+	if err != nil {
+		return err
+	}
+	log.Printf("create tables success ...")
+	return nil
+}
+
+func (s *GormStore) DeleteTables() error {
+	var err error
+	s.Db.Exec("SET FOREIGN_KEY_CHECKS = 0;")
+	for _, tableName := range tableNameList {
+		if s.Db.Migrator().HasTable(tableName) {
+
+			err = s.Db.Migrator().DropTable(tableName)
+			if err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func (s *GormStore) DeleteTable() error {
+	var err error
+	s.Db.Exec("SET FOREIGN_KEY_CHECKS = 0;")
+	for _, tableName := range tableNameList {
+		if s.Db.Migrator().HasTable(tableName) {
+			var clearDataSql = fmt.Sprintf("TRUNCATE TABLE %s", tableName)
+			err = s.Db.Exec(clearDataSql).Error
+			if err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func init() {
+	var err error
+	err = S.Connect2Db()
+	if err != nil {
+		panic(err)
+	}
+	if S.Config.AutoMigrate {
+		err = S.CreateTables()
+		if err != nil {
+			panic(err)
+		}
+	}
+	err = S.Connect2SpecifiedDb()
+	if err != nil {
+		panic(err)
+	}
+}
+
+func Init() {
+	var err error
+	err = S.CreateTables()
+	if err != nil {
+		panic(err)
+	}
+}
+
+func Delete() {
+	var err error
+	err = S.DeleteTables()
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/config_server/service/internal/store/gorm_test.go b/config_server/service/internal/store/gorm_test.go
new file mode 100644
index 0000000000..d8c6311216
--- /dev/null
+++ b/config_server/service/internal/store/gorm_test.go
@@ -0,0 +1,13 @@
+package store
+
+import (
+	"testing"
+)
+
+func TestInitConfigServerDatabase(t *testing.T) {
+	Init()
+}
+
+func TestDeleteConfigServerDatabase(t *testing.T) {
+	Delete()
+}
diff --git a/config_server/service/internal/store/store.go b/config_server/service/internal/store/store.go
new file mode 100644
index 0000000000..b97d826992
--- /dev/null
+++ b/config_server/service/internal/store/store.go
@@ -0,0 +1,8 @@
+package store
+
+type Store interface {
+	Connect() error
+	Close() error
+
+	CreateTables() error
+}
diff --git a/config_server/service/internal/utils/environment.go b/config_server/service/internal/utils/environment.go
new file mode 100644
index 0000000000..e0a0e50d09
--- /dev/null
+++ b/config_server/service/internal/utils/environment.go
@@ -0,0 +1,29 @@
+package utils
+
+import (
+	"log"
+	"path/filepath"
+)
+
+func GetEnvConfig(path string) (map[string]any, error) {
+	envMap := make(map[string]any)
+	err := ReadJson(path, &envMap)
+	if err != nil {
+		return nil, err
+	}
+	return envMap, err
+}
+
+func GetEnvName() (string, error) {
+	path, err := filepath.Abs("cmd/env.json")
+	if err != nil {
+		panic("can not find env file, it should be placed in cmd/env.json")
+	}
+	config, err := GetEnvConfig(path)
+	if err != nil {
+		return "", err
+	}
+	name := config["env"].(string)
+	log.Printf("the environment is %s", name)
+	return name, nil
+}
diff --git a/config_server/service/internal/utils/json.go b/config_server/service/internal/utils/json.go
new file mode 100644
index 0000000000..c8d60b5ab0
--- /dev/null
+++ b/config_server/service/internal/utils/json.go
@@ -0,0 +1,28 @@
+package utils
+
+import (
+	"encoding/json"
+	"log"
+	"os"
+	"path/filepath"
+)
+
+func ReadJson[T any](path string, obj *T) error {
+	file, openErr := os.Open(filepath.Clean(path))
+	if openErr != nil {
+		return openErr
+	}
+	defer func() {
+		if closeErr := file.Close(); closeErr != nil {
+			log.Println("Error closing file: " + closeErr.Error())
+		}
+	}()
+
+	decoder := json.NewDecoder(file)
+	err := decoder.Decode(obj)
+	if err != nil {
+		return err
+	}
+	return nil
+
+}
diff --git a/config_server/service/internal/utils/list.go b/config_server/service/internal/utils/list.go
new file mode 100644
index 0000000000..ff920e5c1b
--- /dev/null
+++ b/config_server/service/internal/utils/list.go
@@ -0,0 +1,40 @@
+package utils
+
+func ContainElement[T comparable](arr []T, val any, eqCondition func(T, any) bool) bool {
+	if arr == nil || len(arr) == 0 {
+		return false
+	}
+	for _, element := range arr {
+		if element == val || eqCondition != nil && eqCondition(element, val) {
+			return true
+		}
+	}
+	return false
+}
+
+func RemoveElement[T comparable](arr []T, val T, eqCondition func(T, T) bool) (bool, []T) {
+	if arr == nil || len(arr) == 0 {
+		return false, arr
+	}
+	for i, element := range arr {
+		if element == val || eqCondition != nil && eqCondition(element, val) {
+			return true, append(arr[:i], arr[i+1:]...)
+		}
+	}
+	return false, arr
+}
+
+// ReplaceElement 如果存在就替换,不存在则返回原数组
+func ReplaceElement[T comparable](arr []T, val T, eqCondition func(T, any) bool) {
+	if eqCondition == nil {
+		return
+	}
+	if arr == nil || len(arr) == 0 {
+		return
+	}
+	for i, element := range arr {
+		if eqCondition(element, val) {
+			arr[i] = val
+		}
+	}
+}
diff --git a/config_server/service/internal/utils/str.go b/config_server/service/internal/utils/str.go
new file mode 100644
index 0000000000..7c9b261336
--- /dev/null
+++ b/config_server/service/internal/utils/str.go
@@ -0,0 +1,7 @@
+package utils
+
+import "strings"
+
+func IsEmptyOrWhitespace(s string) bool {
+	return strings.TrimSpace(s) == ""
+}
diff --git a/config_server/service/internal/utils/task.go b/config_server/service/internal/utils/task.go
new file mode 100644
index 0000000000..15bcd43efd
--- /dev/null
+++ b/config_server/service/internal/utils/task.go
@@ -0,0 +1,56 @@
+package utils
+
+import (
+	"sync"
+	"time"
+)
+
+func TimedTask(timeLimit int64, task func(int64)) {
+	if timeLimit <= 0 {
+		panic("timeLimit 不能小于等于0")
+	}
+	timeLimitNano := timeLimit * int64(time.Second)
+
+	ticker := time.NewTicker(time.Duration(timeLimitNano))
+	defer ticker.Stop()
+
+	for {
+		select {
+		case <-ticker.C:
+			task(timeLimit)
+		}
+	}
+}
+
+func ParallelProcessSlice[T any](arr []T, fun func(int, T)) {
+	if arr == nil || len(arr) == 0 {
+		return
+	}
+	var wg sync.WaitGroup
+
+	for i, v := range arr {
+		wg.Add(1)
+		go func(index int, value T) {
+			defer wg.Done()
+			fun(index, value)
+		}(i, v)
+	}
+
+	wg.Wait()
+}
+
+func ParallelProcessTask[T any](parameter T, tasks ...func(T)) {
+	if tasks == nil || len(tasks) == 0 {
+		return
+	}
+
+	var wg sync.WaitGroup
+	for i, task := range tasks {
+		wg.Add(1)
+		go func(index int, parameter T, taskFunc func(T)) {
+			defer wg.Done()
+			taskFunc(parameter)
+		}(i, parameter, task)
+	}
+	wg.Wait()
+}
diff --git a/config_server/service/manager/agent/agent_manager.go b/config_server/service/manager/agent/agent_manager.go
deleted file mode 100644
index 594a28ff76..0000000000
--- a/config_server/service/manager/agent/agent_manager.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package agentmanager
-
-import (
-	"sync"
-
-	"config-server/model"
-	"config-server/setting"
-)
-
-type AgentManager struct {
-	AgentMessageList agentMessageList
-}
-
-func (a *AgentManager) Init() {
-	a.AgentMessageList.Clear()
-	go a.updateAgentMessage(setting.GetSetting().AgentUpdateInterval)
-}
-
-// batch write message from agent to databse
-
-const (
-	optHeartbeat string = "HEARTBEAT"
-)
-
-type agentMessageList struct {
-	Heartbeat map[string]*model.Agent
-	Mutex     sync.RWMutex
-}
-
-func (a *agentMessageList) Clear() {
-	a.Heartbeat = make(map[string]*model.Agent, 0)
-}
-
-func (a *agentMessageList) Push(opt string, data interface{}) {
-	a.Mutex.Lock()
-	defer a.Mutex.Unlock()
-
-	switch opt {
-	case optHeartbeat:
-		a.Heartbeat[data.(*model.Agent).AgentID] = data.(*model.Agent)
-	}
-}
diff --git a/config_server/service/manager/agent/agent_operator.go b/config_server/service/manager/agent/agent_operator.go
deleted file mode 100644
index 27c6cf55e2..0000000000
--- a/config_server/service/manager/agent/agent_operator.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package agentmanager
-
-import (
-	"log"
-	"sync"
-	"time"
-
-	"config-server/common"
-	"config-server/model"
-	proto "config-server/proto"
-	"config-server/store"
-)
-
-func (a *AgentManager) HeartBeat(req *proto.HeartBeatRequest, res *proto.HeartBeatResponse) (int, *proto.HeartBeatResponse) {
-	agent := new(model.Agent)
-	agent.AgentID = req.AgentId
-	agent.AgentType = req.AgentType
-	agent.Attributes.ParseProto(req.Attributes)
-	agent.Tags = req.Tags
-	agent.RunningStatus = req.RunningStatus
-	agent.StartupTime = req.StartupTime
-	agent.Interval = req.Interval
-
-	a.AgentMessageList.Push(optHeartbeat, agent)
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Send heartbeat success"
-	return common.Accept.Status, res
-}
-
-var wg sync.WaitGroup
-
-func (a *AgentManager) updateAgentMessage(interval int) {
-	ticker := time.NewTicker(time.Duration(interval) * time.Second)
-	defer ticker.Stop()
-
-	for range ticker.C {
-		wg.Add(1)
-		go a.batchUpdateAgentMessage()
-		wg.Wait()
-	}
-}
-
-func (a *AgentManager) batchUpdateAgentMessage() {
-	s := store.GetStore()
-	b := store.CreateBacth()
-
-	a.AgentMessageList.Mutex.Lock()
-	for k, v := range a.AgentMessageList.Heartbeat {
-		b.Update(common.TypeAgent, k, v)
-	}
-	a.AgentMessageList.Heartbeat = make(map[string]*model.Agent, 0)
-	a.AgentMessageList.Mutex.Unlock()
-
-	writeBatchErr := s.WriteBatch(b)
-	if writeBatchErr != nil {
-		log.Println(writeBatchErr)
-	}
-
-	wg.Done()
-}
diff --git a/config_server/service/manager/config/agent_operator.go b/config_server/service/manager/config/agent_operator.go
deleted file mode 100644
index 6402583a98..0000000000
--- a/config_server/service/manager/config/agent_operator.go
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package configmanager
-
-import (
-	"fmt"
-	"log"
-	"time"
-
-	"config-server/common"
-	"config-server/model"
-	proto "config-server/proto"
-	"config-server/store"
-)
-
-func (c *ConfigManager) updateConfigList(interval int) {
-	ticker := time.NewTicker(time.Duration(interval) * time.Second)
-	defer ticker.Stop()
-
-	for range ticker.C {
-		s := store.GetStore()
-		configList, getAllErr := s.GetAll(common.TypeConfigDetail)
-		if getAllErr != nil {
-			log.Println(getAllErr)
-			continue
-		} else {
-			c.ConfigListMutex.Lock()
-			c.ConfigList = make(map[string]*model.ConfigDetail, 0)
-			for _, config := range configList {
-				c.ConfigList[config.(*model.ConfigDetail).Name] = config.(*model.ConfigDetail)
-			}
-			c.ConfigListMutex.Unlock()
-		}
-	}
-}
-
-func (c *ConfigManager) CheckConfigUpdatesWhenHeartbeat(req *proto.HeartBeatRequest, res *proto.HeartBeatResponse) (int, *proto.HeartBeatResponse) {
-	pipelineConfigs := make([]*proto.ConfigCheckResult, 0)
-	agentConfigs := make([]*proto.ConfigCheckResult, 0)
-	s := store.GetStore()
-
-	// get all configs connected to agent group whose tag is same as agent's
-	SelectedConfigs := make(map[string]*model.ConfigDetail)
-	agentGroupList, getAllErr := s.GetAll(common.TypeAgentGROUP)
-	if getAllErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getAllErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	for _, agentGroup := range agentGroupList {
-		match := func() bool {
-			for _, v := range agentGroup.(*model.AgentGroup).Tags {
-				for _, tag := range req.Tags {
-					if v.Value == tag {
-						return true
-					}
-				}
-			}
-			return false
-		}()
-		if match || agentGroup.(*model.AgentGroup).Name == "default" {
-			for k := range agentGroup.(*model.AgentGroup).AppliedConfigs {
-				// Check if config k exist
-				c.ConfigListMutex.RLock()
-				config, ok := c.ConfigList[k]
-				c.ConfigListMutex.RUnlock()
-				if !ok {
-					res.Code = proto.RespCode_INVALID_PARAMETER
-					res.Message = fmt.Sprintf("Config %s doesn't exist.", k)
-					return common.ConfigNotExist.Status, res
-				}
-
-				if config.DelTag {
-					res.Code = proto.RespCode_INVALID_PARAMETER
-					res.Message = fmt.Sprintf("Config %s doesn't exist.", k)
-					return common.ConfigNotExist.Status, res
-				}
-
-				SelectedConfigs[k] = config
-			}
-		}
-	}
-
-	// deleted or modified configs, and delete same configs in SelectedConfigs
-	for _, k := range req.PipelineConfigs {
-		config, ok := SelectedConfigs[k.Name]
-		if !ok {
-			result := new(proto.ConfigCheckResult)
-			result.Type = proto.ConfigType_PIPELINE_CONFIG
-			result.Name = k.Name
-			result.OldVersion = k.Version
-			result.NewVersion = k.Version
-			result.Context = k.Context
-			result.CheckStatus = proto.CheckStatus_DELETED
-			pipelineConfigs = append(pipelineConfigs, result)
-		} else if ok {
-			if config.Version > k.Version {
-				result := new(proto.ConfigCheckResult)
-				result.Type = proto.ConfigType_PIPELINE_CONFIG
-				result.Name = config.Name
-				result.OldVersion = k.Version
-				result.NewVersion = config.Version
-				result.Context = config.Context
-				result.CheckStatus = proto.CheckStatus_MODIFIED
-				pipelineConfigs = append(pipelineConfigs, result)
-			}
-			delete(SelectedConfigs, k.Name)
-		}
-	}
-
-	for _, k := range req.AgentConfigs {
-		config, ok := SelectedConfigs[k.Name]
-		if !ok {
-			result := new(proto.ConfigCheckResult)
-			result.Type = proto.ConfigType_AGENT_CONFIG
-			result.Name = k.Name
-			result.OldVersion = k.Version
-			result.NewVersion = k.Version
-			result.Context = k.Context
-			result.CheckStatus = proto.CheckStatus_DELETED
-			agentConfigs = append(agentConfigs, result)
-		} else if ok {
-			if config.Version > k.Version {
-				result := new(proto.ConfigCheckResult)
-				result.Type = proto.ConfigType_AGENT_CONFIG
-				result.Name = config.Name
-				result.OldVersion = k.Version
-				result.NewVersion = config.Version
-				result.Context = config.Context
-				result.CheckStatus = proto.CheckStatus_MODIFIED
-				agentConfigs = append(agentConfigs, result)
-			}
-			delete(SelectedConfigs, k.Name)
-		}
-	}
-
-	// new configs
-	for _, config := range SelectedConfigs {
-		result := new(proto.ConfigCheckResult)
-		result.Type = model.ConfigType[config.Type]
-		result.Name = config.Name
-		result.OldVersion = 0
-		result.NewVersion = config.Version
-		result.Context = config.Context
-		result.CheckStatus = proto.CheckStatus_NEW
-		switch result.Type {
-		case proto.ConfigType_AGENT_CONFIG:
-			agentConfigs = append(agentConfigs, result)
-		case proto.ConfigType_PIPELINE_CONFIG:
-			pipelineConfigs = append(pipelineConfigs, result)
-		}
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message += "Get config update infos success"
-	res.AgentCheckResults = agentConfigs
-	res.PipelineCheckResults = pipelineConfigs
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) FetchAgentConfig(req *proto.FetchAgentConfigRequest, res *proto.FetchAgentConfigResponse) (int, *proto.FetchAgentConfigResponse) {
-	ans := make([]*proto.ConfigDetail, 0)
-
-	// do something about attributes
-
-	for _, configInfo := range req.ReqConfigs {
-		c.ConfigListMutex.RLock()
-		config, ok := c.ConfigList[configInfo.Name]
-		c.ConfigListMutex.RUnlock()
-		if !ok {
-			res.Code = proto.RespCode_INVALID_PARAMETER
-			res.Message += fmt.Sprintf("Config %s doesn't exist.\n", configInfo.Name)
-			continue
-		}
-
-		if config.DelTag {
-			res.Code = proto.RespCode_INVALID_PARAMETER
-			res.Message = fmt.Sprintf("Config %s doesn't exist.\n", configInfo.Name)
-			continue
-		}
-		if config.Type == configInfo.Type.String() {
-			ans = append(ans, config.ToProto())
-		}
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Get Agent Config details success"
-	res.ConfigDetails = ans
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) FetchPipelineConfig(req *proto.FetchPipelineConfigRequest, res *proto.FetchPipelineConfigResponse) (int, *proto.FetchPipelineConfigResponse) {
-	ans := make([]*proto.ConfigDetail, 0)
-
-	for _, configInfo := range req.ReqConfigs {
-		c.ConfigListMutex.RLock()
-		config, ok := c.ConfigList[configInfo.Name]
-		c.ConfigListMutex.RUnlock()
-		if !ok {
-			res.Code = proto.RespCode_INVALID_PARAMETER
-			res.Message += fmt.Sprintf("Config %s doesn't exist.\n", configInfo.Name)
-			continue
-		}
-
-		if config.DelTag {
-			res.Code = proto.RespCode_INVALID_PARAMETER
-			res.Message = fmt.Sprintf("Config %s doesn't exist.\n", configInfo.Name)
-			continue
-		}
-		if config.Type == configInfo.Type.String() {
-			ans = append(ans, config.ToProto())
-		}
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Get Agent Config details success"
-	res.ConfigDetails = ans
-	return common.Accept.Status, res
-}
diff --git a/config_server/service/manager/config/config_manager.go b/config_server/service/manager/config/config_manager.go
deleted file mode 100644
index 045eed4fc5..0000000000
--- a/config_server/service/manager/config/config_manager.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package configmanager
-
-import (
-	"sync"
-
-	"config-server/common"
-	"config-server/model"
-	"config-server/setting"
-	"config-server/store"
-)
-
-type ConfigManager struct {
-	ConfigList      map[string]*model.ConfigDetail
-	ConfigListMutex *sync.RWMutex
-}
-
-func (c *ConfigManager) Init() {
-	c.ConfigList = make(map[string]*model.ConfigDetail)
-	c.ConfigListMutex = new(sync.RWMutex)
-	go c.updateConfigList(setting.GetSetting().ConfigSyncInterval)
-
-	s := store.GetStore()
-	ok, hasErr := s.Has(common.TypeAgentGROUP, "default")
-	if hasErr != nil {
-		panic(hasErr)
-	}
-	if ok {
-		return
-	}
-	agentGroup := new(model.AgentGroup)
-	agentGroup.Name = "default"
-	agentGroup.Tags = make([]model.AgentGroupTag, 0)
-	agentGroup.AppliedConfigs = map[string]int64{}
-	agentGroup.Description = "Default agent group, include all Agents."
-
-	addErr := s.Add(common.TypeAgentGROUP, agentGroup.Name, agentGroup)
-	if addErr != nil {
-		panic(addErr)
-	}
-}
diff --git a/config_server/service/manager/config/user_operator.go b/config_server/service/manager/config/user_operator.go
deleted file mode 100644
index 326deafcca..0000000000
--- a/config_server/service/manager/config/user_operator.go
+++ /dev/null
@@ -1,691 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package configmanager
-
-import (
-	"fmt"
-	"time"
-
-	"config-server/common"
-	"config-server/model"
-	proto "config-server/proto"
-	"config-server/store"
-)
-
-func (c *ConfigManager) CreateConfig(req *proto.CreateConfigRequest, res *proto.CreateConfigResponse) (int, *proto.CreateConfigResponse) {
-	s := store.GetStore()
-
-	ok, hasErr := s.Has(common.TypeConfigDetail, req.ConfigDetail.Name)
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if ok {
-		value, getErr := s.Get(common.TypeConfigDetail, req.ConfigDetail.Name)
-		if getErr != nil {
-			res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-			res.Message = getErr.Error()
-			return common.InternalServerError.Status, res
-		}
-		config := value.(*model.ConfigDetail)
-
-		if !config.DelTag { // exsit
-			res.Code = proto.RespCode_INVALID_PARAMETER
-			res.Message = fmt.Sprintf("Config %s already exists.", req.ConfigDetail.Name)
-			return common.ConfigAlreadyExist.Status, res
-		}
-		// exist but has delete tag
-		verison := config.Version
-		config.ParseProto(req.ConfigDetail)
-		config.Version = verison + 1
-		config.DelTag = false
-
-		updateErr := s.Update(common.TypeConfigDetail, config.Name, config)
-		if updateErr != nil {
-			res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-			res.Message = updateErr.Error()
-			return common.InternalServerError.Status, res
-		}
-
-		res.Code = proto.RespCode_ACCEPT
-		res.Message = "Add config success"
-		return common.Accept.Status, res
-	}
-	// doesn't exist
-	config := new(model.ConfigDetail)
-	config.ParseProto(req.ConfigDetail)
-	config.Version = 0
-	config.DelTag = false
-
-	addErr := s.Add(common.TypeConfigDetail, config.Name, config)
-	if addErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = addErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Add config success"
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) UpdateConfig(req *proto.UpdateConfigRequest, res *proto.UpdateConfigResponse) (int, *proto.UpdateConfigResponse) {
-	s := store.GetStore()
-	ok, hasErr := s.Has(common.TypeConfigDetail, req.ConfigDetail.Name)
-
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigDetail.Name)
-		return common.ConfigNotExist.Status, res
-	}
-
-	value, getErr := s.Get(common.TypeConfigDetail, req.ConfigDetail.Name)
-	if getErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	config := value.(*model.ConfigDetail)
-
-	if config.DelTag {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigDetail.Name)
-		return common.ConfigNotExist.Status, res
-	}
-	version := config.Version
-	config.ParseProto(req.ConfigDetail)
-	config.Version = version + 1
-
-	updateErr := s.Update(common.TypeConfigDetail, config.Name, config)
-	if updateErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = updateErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Update config success"
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) DeleteConfig(req *proto.DeleteConfigRequest, res *proto.DeleteConfigResponse) (int, *proto.DeleteConfigResponse) {
-	s := store.GetStore()
-	ok, hasErr := s.Has(common.TypeConfigDetail, req.ConfigName)
-
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
-		return common.ConfigNotExist.Status, res
-	}
-	value, getErr := s.Get(common.TypeConfigDetail, req.ConfigName)
-	if getErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	config := value.(*model.ConfigDetail)
-
-	if config.DelTag {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
-		return common.ConfigNotExist.Status, res
-	}
-	// Check if this config bind with agent groups
-	checkReq := proto.GetAppliedAgentGroupsRequest{}
-	checkRes := &proto.GetAppliedAgentGroupsResponse{}
-	checkReq.ConfigName = req.ConfigName
-	status, checkRes := c.GetAppliedAgentGroups(&checkReq, checkRes)
-	if status != 200 {
-		res.Code = checkRes.Code
-		res.Message = checkRes.Message
-		return status, res
-	}
-	if len(checkRes.AgentGroupNames) > 0 {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = fmt.Sprintf("Config %s was applied to some agent groups, cannot be deleted.", req.ConfigName)
-		return common.InternalServerError.Status, res
-	}
-
-	config.DelTag = true
-	config.Version++
-
-	updateErr := s.Update(common.TypeConfigDetail, req.ConfigName, config)
-	if updateErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = updateErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Delete config success"
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) GetConfig(req *proto.GetConfigRequest, res *proto.GetConfigResponse) (int, *proto.GetConfigResponse) {
-	s := store.GetStore()
-	ok, hasErr := s.Has(common.TypeConfigDetail, req.ConfigName)
-
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
-		return common.ConfigNotExist.Status, res
-	}
-	value, getErr := s.Get(common.TypeConfigDetail, req.ConfigName)
-	if getErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	config := value.(*model.ConfigDetail)
-
-	if config.DelTag {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
-		return common.ConfigNotExist.Status, res
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Get config success"
-	res.ConfigDetail = config.ToProto()
-	return common.Accept.Status, res
-
-}
-
-func (c *ConfigManager) ListConfigs(req *proto.ListConfigsRequest, res *proto.ListConfigsResponse) (int, *proto.ListConfigsResponse) {
-	s := store.GetStore()
-	configs, getAllErr := s.GetAll(common.TypeConfigDetail)
-
-	if getAllErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getAllErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	ans := make([]model.ConfigDetail, 0)
-	for _, value := range configs {
-		config := value.(*model.ConfigDetail)
-		if !config.DelTag {
-			ans = append(ans, *config)
-		}
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Get config list success"
-	res.ConfigDetails = make([]*proto.ConfigDetail, 0)
-	for _, v := range ans {
-		res.ConfigDetails = append(res.ConfigDetails, v.ToProto())
-	}
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) GetAppliedAgentGroups(req *proto.GetAppliedAgentGroupsRequest, res *proto.GetAppliedAgentGroupsResponse) (int, *proto.GetAppliedAgentGroupsResponse) {
-	ans := make([]string, 0)
-	s := store.GetStore()
-
-	// Check config exist
-	ok, hasErr := s.Has(common.TypeConfigDetail, req.ConfigName)
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
-		return common.ConfigNotExist.Status, res
-	}
-	value, getErr := s.Get(common.TypeConfigDetail, req.ConfigName)
-	if getErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	config := value.(*model.ConfigDetail)
-
-	if config.DelTag {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
-		return common.ConfigNotExist.Status, res
-	}
-
-	// Get agent group names
-	agentGroupList, getAllErr := s.GetAll(common.TypeAgentGROUP)
-	if getAllErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getAllErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	for _, g := range agentGroupList {
-		if _, ok := g.(*model.AgentGroup).AppliedConfigs[req.ConfigName]; ok {
-			ans = append(ans, g.(*model.AgentGroup).Name)
-		}
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Get group list success"
-	res.AgentGroupNames = ans
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) CreateAgentGroup(req *proto.CreateAgentGroupRequest, res *proto.CreateAgentGroupResponse) (int, *proto.CreateAgentGroupResponse) {
-	s := store.GetStore()
-	ok, hasErr := s.Has(common.TypeAgentGROUP, req.AgentGroup.GroupName)
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group %s already exists.", req.AgentGroup.GroupName)
-		return common.AgentGroupAlreadyExist.Status, res
-	}
-	agentGroup := new(model.AgentGroup)
-	agentGroup.ParseProto(req.AgentGroup)
-	agentGroup.AppliedConfigs = make(map[string]int64, 0)
-
-	addErr := s.Add(common.TypeAgentGROUP, agentGroup.Name, agentGroup)
-	if addErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = addErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Add agent group success"
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) UpdateAgentGroup(req *proto.UpdateAgentGroupRequest, res *proto.UpdateAgentGroupResponse) (int, *proto.UpdateAgentGroupResponse) {
-	s := store.GetStore()
-	ok, hasErr := s.Has(common.TypeAgentGROUP, req.AgentGroup.GroupName)
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.AgentGroup.GroupName)
-		return common.AgentGroupNotExist.Status, res
-	}
-	value, getErr := s.Get(common.TypeAgentGROUP, req.AgentGroup.GroupName)
-	if getErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	agentGroup := value.(*model.AgentGroup)
-
-	agentGroup.ParseProto(req.AgentGroup)
-
-	updateErr := s.Update(common.TypeAgentGROUP, req.AgentGroup.GroupName, agentGroup)
-	if updateErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = updateErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Update agent group success"
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) DeleteAgentGroup(req *proto.DeleteAgentGroupRequest, res *proto.DeleteAgentGroupResponse) (int, *proto.DeleteAgentGroupResponse) {
-	s := store.GetStore()
-
-	if req.GroupName == "default" {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = "Cannot delete agent group 'default'"
-		return common.BadRequest.Status, res
-	}
-
-	ok, hasErr := s.Has(common.TypeAgentGROUP, req.GroupName)
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.GroupName)
-		return common.AgentGroupNotExist.Status, res
-	}
-	// Check if this config bind with agent groups
-	checkReq := proto.GetAppliedConfigsForAgentGroupRequest{}
-	checkRes := &proto.GetAppliedConfigsForAgentGroupResponse{}
-	checkReq.GroupName = req.GroupName
-	status, checkRes := c.GetAppliedConfigsForAgentGroup(&checkReq, checkRes)
-	if status != 200 {
-		res.Code = checkRes.Code
-		res.Message = checkRes.Message
-		return status, res
-	}
-	if len(checkRes.ConfigNames) > 0 {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = fmt.Sprintf("Agent group %s was applied to some configs, cannot be deleted.", req.GroupName)
-		return common.InternalServerError.Status, res
-	}
-
-	deleteErr := s.Delete(common.TypeAgentGROUP, req.GroupName)
-	if deleteErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = deleteErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Delete agent group success"
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) GetAgentGroup(req *proto.GetAgentGroupRequest, res *proto.GetAgentGroupResponse) (int, *proto.GetAgentGroupResponse) {
-	s := store.GetStore()
-	ok, hasErr := s.Has(common.TypeAgentGROUP, req.GroupName)
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.GroupName)
-		return common.AgentGroupNotExist.Status, res
-	}
-	agentGroup, getErr := s.Get(common.TypeAgentGROUP, req.GroupName)
-	if getErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Get agent group success"
-	res.AgentGroup = agentGroup.(*model.AgentGroup).ToProto()
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) ListAgentGroups(req *proto.ListAgentGroupsRequest, res *proto.ListAgentGroupsResponse) (int, *proto.ListAgentGroupsResponse) {
-	s := store.GetStore()
-	agentGroupList, getAllErr := s.GetAll(common.TypeAgentGROUP)
-	if getAllErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		return common.InternalServerError.Status, res
-	}
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Get agent group list success"
-	res.AgentGroups = []*proto.AgentGroup{}
-	for _, v := range agentGroupList {
-		res.AgentGroups = append(res.AgentGroups, v.(*model.AgentGroup).ToProto())
-	}
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) ListAgents(req *proto.ListAgentsRequest, res *proto.ListAgentsResponse) (int, *proto.ListAgentsResponse) {
-	ans := make([]*proto.Agent, 0)
-	s := store.GetStore()
-
-	var agentGroup *model.AgentGroup
-
-	// get agent group
-	ok, hasErr := s.Has(common.TypeAgentGROUP, req.GroupName)
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.GroupName)
-		return common.AgentGroupNotExist.Status, res
-	}
-	value, getErr := s.Get(common.TypeAgentGROUP, req.GroupName)
-	if getErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	agentGroup = value.(*model.AgentGroup)
-
-	agentList, getAllErr := s.GetAll(common.TypeAgent)
-	if getAllErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getAllErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	for _, v := range agentList {
-		agent := v.(*model.Agent)
-		match := func() bool {
-			for _, v := range agentGroup.Tags {
-				for _, tag := range agent.Tags {
-					if v.Value == tag {
-						return true
-					}
-				}
-			}
-			return false
-		}()
-		if match || agentGroup.Name == "default" {
-			ans = append(ans, agent.ToProto())
-		}
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Get agent list success"
-	res.Agents = ans
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) GetAppliedConfigsForAgentGroup(req *proto.GetAppliedConfigsForAgentGroupRequest, res *proto.GetAppliedConfigsForAgentGroupResponse) (int, *proto.GetAppliedConfigsForAgentGroupResponse) {
-	ans := make([]string, 0)
-	s := store.GetStore()
-	var agentGroup *model.AgentGroup
-
-	// Get agent group
-	ok, hasErr := s.Has(common.TypeAgentGROUP, req.GroupName)
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.GroupName)
-		return common.AgentGroupNotExist.Status, res
-	}
-	value, getErr := s.Get(common.TypeAgentGROUP, req.GroupName)
-	if getErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	agentGroup = value.(*model.AgentGroup)
-
-	for k := range agentGroup.AppliedConfigs {
-		ans = append(ans, k)
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Get agent group's applied configs success"
-	res.ConfigNames = ans
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) ApplyConfigToAgentGroup(req *proto.ApplyConfigToAgentGroupRequest, res *proto.ApplyConfigToAgentGroupResponse) (int, *proto.ApplyConfigToAgentGroupResponse) {
-	s := store.GetStore()
-	var agentGroup *model.AgentGroup
-	var config *model.ConfigDetail
-
-	// Get agent group
-	ok, hasErr := s.Has(common.TypeAgentGROUP, req.GroupName)
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.GroupName)
-		return common.AgentGroupNotExist.Status, res
-	}
-	value, getErr := s.Get(common.TypeAgentGROUP, req.GroupName)
-	if getErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	agentGroup = value.(*model.AgentGroup)
-
-	// Get config
-	ok, hasErr = s.Has(common.TypeConfigDetail, req.ConfigName)
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
-		return common.ConfigNotExist.Status, res
-	}
-	value, getErr = s.Get(common.TypeConfigDetail, req.ConfigName)
-	if getErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	config = value.(*model.ConfigDetail)
-
-	if config.DelTag {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
-		return common.ConfigNotExist.Status, res
-	}
-
-	// Check if agent group already has config
-	if agentGroup.AppliedConfigs == nil {
-		agentGroup.AppliedConfigs = make(map[string]int64)
-	}
-	if _, ok := agentGroup.AppliedConfigs[config.Name]; ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group %s already has config %s.", req.GroupName, req.ConfigName)
-		return common.ConfigAlreadyExist.Status, res
-	}
-	agentGroup.AppliedConfigs[config.Name] = time.Now().Unix()
-
-	updateErr := store.GetStore().Update(common.TypeAgentGROUP, req.GroupName, agentGroup)
-	if updateErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = updateErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Add config to agent group success"
-	return common.Accept.Status, res
-}
-
-func (c *ConfigManager) RemoveConfigFromAgentGroup(req *proto.RemoveConfigFromAgentGroupRequest, res *proto.RemoveConfigFromAgentGroupResponse) (int, *proto.RemoveConfigFromAgentGroupResponse) {
-	s := store.GetStore()
-	var agentGroup *model.AgentGroup
-	var config *model.ConfigDetail
-
-	// Get agent group
-	ok, hasErr := s.Has(common.TypeAgentGROUP, req.GroupName)
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.GroupName)
-		return common.AgentGroupNotExist.Status, res
-	}
-	value, getErr := s.Get(common.TypeAgentGROUP, req.GroupName)
-	if getErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	agentGroup = value.(*model.AgentGroup)
-
-	// Get config
-	ok, hasErr = s.Has(common.TypeConfigDetail, req.ConfigName)
-	if hasErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = hasErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	if !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
-		return common.ConfigNotExist.Status, res
-	}
-	value, getErr = s.Get(common.TypeConfigDetail, req.ConfigName)
-	if getErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = getErr.Error()
-		return common.InternalServerError.Status, res
-	}
-	config = value.(*model.ConfigDetail)
-
-	if config.DelTag {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
-		return common.ConfigNotExist.Status, res
-	}
-
-	if agentGroup.AppliedConfigs == nil {
-		agentGroup.AppliedConfigs = make(map[string]int64)
-	}
-	if _, ok := agentGroup.AppliedConfigs[config.Name]; !ok {
-		res.Code = proto.RespCode_INVALID_PARAMETER
-		res.Message = fmt.Sprintf("Agent group %s doesn't have config %s.", req.GroupName, req.ConfigName)
-		return common.ConfigNotExist.Status, res
-	}
-	delete(agentGroup.AppliedConfigs, config.Name)
-
-	updateErr := store.GetStore().Update(common.TypeAgentGROUP, req.GroupName, agentGroup)
-	if updateErr != nil {
-		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
-		res.Message = updateErr.Error()
-		return common.InternalServerError.Status, res
-	}
-
-	res.Code = proto.RespCode_ACCEPT
-	res.Message = "Remove config from agent group success"
-	return common.Accept.Status, res
-}
diff --git a/config_server/service/manager/manager.go b/config_server/service/manager/manager.go
deleted file mode 100644
index 7af038594d..0000000000
--- a/config_server/service/manager/manager.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package manager
-
-import (
-	agentManager "config-server/manager/agent"
-	configManager "config-server/manager/config"
-)
-
-var myAgentManager *agentManager.AgentManager
-var myConfigManager *configManager.ConfigManager
-
-func AgentManager() *agentManager.AgentManager {
-	return myAgentManager
-}
-
-func ConfigManager() *configManager.ConfigManager {
-	return myConfigManager
-}
-
-func init() {
-	myAgentManager = new(agentManager.AgentManager)
-	myAgentManager.Init()
-
-	myConfigManager = new(configManager.ConfigManager)
-	myConfigManager.Init()
-}
diff --git a/config_server/service/model/agent.go b/config_server/service/model/agent.go
deleted file mode 100644
index 94fda23059..0000000000
--- a/config_server/service/model/agent.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"config-server/common"
-	proto "config-server/proto"
-	"database/sql/driver"
-	"encoding/json"
-	"fmt"
-
-	"gorm.io/gorm"
-)
-
-type AgentAttributes struct {
-	Version  string            `json:"Version"`
-	Category string            `json:"Category"`
-	IP       string            `json:"IP"`
-	Hostname string            `json:"Hostname"`
-	Region   string            `json:"Region"`
-	Zone     string            `json:"Zone"`
-	Extras   map[string]string `json:"Extras"`
-}
-
-func (a *AgentAttributes) Scan(value interface{}) error {
-	if value == nil {
-		return nil
-	}
-
-	b, ok := value.([]byte)
-	if !ok {
-		return fmt.Errorf("value is not []byte, value: %v", value)
-	}
-
-	return json.Unmarshal(b, a)
-}
-
-func (a AgentAttributes) Value() (driver.Value, error) {
-	v, err := json.Marshal(a)
-	if err != nil {
-		return nil, err
-	}
-	return v, nil
-}
-
-func (a *AgentAttributes) ToProto() *proto.AgentAttributes {
-	pa := new(proto.AgentAttributes)
-	pa.Version = a.Version
-	pa.Category = a.Category
-	pa.Ip = a.IP
-	pa.Hostname = a.Hostname
-	pa.Region = a.Region
-	pa.Zone = a.Zone
-	pa.Extras = a.Extras
-	return pa
-}
-
-func (a *AgentAttributes) ParseProto(pa *proto.AgentAttributes) {
-	a.Version = pa.Version
-	a.Category = pa.Category
-	a.IP = pa.Ip
-	a.Hostname = pa.Hostname
-	a.Region = pa.Region
-	a.Zone = pa.Zone
-	a.Extras = pa.Extras
-}
-
-type Agent struct {
-	AgentID        string          `json:"AgentID" gorm:"primaryKey;column:agent_id"`
-	AgentType      string          `json:"AgentType"`
-	Attributes     AgentAttributes `json:"Attributes"`
-	Tags           []string        `json:"Tags" gorm:"-"`
-	SerializedTags string          `json:"-" gorm:"column:tags;type:json"`
-	RunningStatus  string          `json:"RunningStatus"`
-	StartupTime    int64           `json:"StartupTime"`
-	Interval       int32           `json:"Interval"`
-}
-
-func (Agent) TableName() string {
-	return common.TypeAgent
-}
-
-func (a *Agent) AfterFind(tx *gorm.DB) (err error) {
-	if a.SerializedTags == "" {
-		return nil
-	}
-	err = json.Unmarshal([]byte(a.SerializedTags), &a.Tags)
-	if err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (a *Agent) BeforeSave(tx *gorm.DB) (err error) {
-	if a.Tags == nil {
-		return nil
-	}
-	data, err := json.Marshal(a.Tags)
-	if err != nil {
-		return err
-	}
-	tx.Statement.SetColumn("tags", string(data))
-
-	return nil
-}
-
-func (a *Agent) ToProto() *proto.Agent {
-	pa := new(proto.Agent)
-	pa.AgentId = a.AgentID
-	pa.AgentType = a.AgentType
-	pa.Attributes = a.Attributes.ToProto()
-	pa.Tags = a.Tags
-	pa.RunningStatus = a.RunningStatus
-	pa.StartupTime = a.StartupTime
-	pa.Interval = a.Interval
-	return pa
-}
-
-func (a *Agent) ParseProto(pa *proto.Agent) {
-	a.AgentID = pa.AgentId
-	a.AgentType = pa.AgentType
-	a.Attributes.ParseProto(pa.Attributes)
-	a.Tags = pa.Tags
-	a.RunningStatus = pa.RunningStatus
-	a.StartupTime = pa.StartupTime
-	a.Interval = pa.Interval
-}
diff --git a/config_server/service/model/agent_group.go b/config_server/service/model/agent_group.go
deleted file mode 100644
index f16e996ccb..0000000000
--- a/config_server/service/model/agent_group.go
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"config-server/common"
-	proto "config-server/proto"
-	"encoding/json"
-
-	"gorm.io/gorm"
-)
-
-type AgentGroupTag struct {
-	Name  string `json:"Name"`
-	Value string `json:"Value"`
-}
-
-type AgentGroup struct {
-	Name                     string           `json:"Name" gorm:"primaryKey"`
-	Description              string           `json:"Description"`
-	Tags                     []AgentGroupTag  `json:"Tags" gorm:"-"`
-	SerializedTags           string           `json:"-" gorm:"column:tags;type:json"`
-	AppliedConfigs           map[string]int64 `json:"AppliedConfigs" gorm:"-"`
-	SerializedAppliedConfigs string           `json:"-" gorm:"column:applied_configs;type:json"`
-}
-
-func (AgentGroup) TableName() string {
-	return common.TypeAgentGROUP
-}
-
-func (a *AgentGroup) AfterFind(tx *gorm.DB) (err error) {
-	if a.SerializedTags != "" {
-		err = json.Unmarshal([]byte(a.SerializedTags), &a.Tags)
-		if err != nil {
-			return err
-		}
-	}
-	if a.SerializedAppliedConfigs != "" {
-		err = json.Unmarshal([]byte(a.SerializedAppliedConfigs), &a.AppliedConfigs)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (a *AgentGroup) BeforeSave(tx *gorm.DB) (err error) {
-	if a.Tags != nil {
-		data, err := json.Marshal(a.Tags)
-		if err != nil {
-			return err
-		}
-		tx.Statement.SetColumn("tags", string(data))
-	}
-	if a.AppliedConfigs != nil {
-		data, err := json.Marshal(a.AppliedConfigs)
-		if err != nil {
-			return err
-		}
-		tx.Statement.SetColumn("applied_configs", string(data))
-	}
-	return nil
-}
-
-func (a *AgentGroup) ToProto() *proto.AgentGroup {
-	pa := new(proto.AgentGroup)
-	pa.GroupName = a.Name
-	pa.Description = a.Description
-	pa.Tags = make([]*proto.AgentGroupTag, 0)
-	for _, v := range a.Tags {
-		tag := new(proto.AgentGroupTag)
-		tag.Name = v.Name
-		tag.Value = v.Value
-		pa.Tags = append(pa.Tags, tag)
-	}
-	return pa
-}
-
-func (a *AgentGroup) ParseProto(pa *proto.AgentGroup) {
-	a.Name = pa.GroupName
-	a.Description = pa.Description
-	a.Tags = make([]AgentGroupTag, 0)
-	for _, v := range pa.Tags {
-		tag := new(AgentGroupTag)
-		tag.Name = v.Name
-		tag.Value = v.Value
-		a.Tags = append(a.Tags, *tag)
-	}
-}
diff --git a/config_server/service/model/collection_config.go b/config_server/service/model/collection_config.go
deleted file mode 100644
index 9b776d2dc2..0000000000
--- a/config_server/service/model/collection_config.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"config-server/common"
-	proto "config-server/proto"
-)
-
-var ConfigType = map[string]proto.ConfigType{
-	"PIPELINE_CONFIG": proto.ConfigType_PIPELINE_CONFIG,
-	"AGENT_CONFIG":    proto.ConfigType_AGENT_CONFIG,
-}
-
-type ConfigDetail struct {
-	Type    string `json:"Type"`
-	Name    string `json:"Name" gorm:"primaryKey"`
-	Version int64  `json:"Version"`
-	Context string `json:"Context"`
-	Detail  string `json:"Detail"`
-	DelTag  bool   `json:"DelTag"`
-}
-
-func (ConfigDetail) TableName() string {
-	return common.TypeConfigDetail
-}
-
-func (c *ConfigDetail) ToProto() *proto.ConfigDetail {
-	pc := new(proto.ConfigDetail)
-	pc.Type = ConfigType[c.Type]
-	pc.Name = c.Name
-	pc.Version = c.Version
-	pc.Context = c.Context
-	pc.Detail = c.Detail
-	return pc
-}
-
-func (c *ConfigDetail) ParseProto(pc *proto.ConfigDetail) {
-	c.Type = pc.Type.String()
-	c.Name = pc.Name
-	c.Version = pc.Version
-	c.Context = pc.Context
-	c.Detail = pc.Detail
-}
-
-type Command struct {
-	Type string            `json:"Type"`
-	Name string            `json:"Name"`
-	ID   string            `json:"ID"`
-	Args map[string]string `json:"Args"`
-}
-
-func (c *Command) ToProto() *proto.Command {
-	pc := new(proto.Command)
-	pc.Type = c.Type
-	pc.Name = c.Name
-	pc.Id = c.ID
-	pc.Args = c.Args
-	return pc
-}
-
-func (c *Command) ParseProto(pc *proto.Command) {
-	c.Type = pc.Type
-	c.Name = pc.Name
-	c.ID = pc.Id
-	c.Args = pc.Args
-}
diff --git a/config_server/service/model/model_type.go b/config_server/service/model/model_type.go
deleted file mode 100644
index 9e0b8625ea..0000000000
--- a/config_server/service/model/model_type.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2024 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package model
-
-import (
-	"config-server/common"
-	"reflect"
-)
-
-var Models = map[string]interface{}{
-	common.TypeAgentAttributes: &AgentAttributes{},
-	common.TypeAgent:           &Agent{},
-	common.TypeConfigDetail:    &ConfigDetail{},
-	common.TypeAgentGROUP:      &AgentGroup{},
-	common.TypeCommand:         &Command{},
-}
-
-var ModelTypes = map[string]reflect.Type{
-	common.TypeAgentAttributes: reflect.TypeOf(([]*AgentAttributes)(nil)),
-	common.TypeAgent:           reflect.TypeOf(([]*Agent)(nil)),
-	common.TypeConfigDetail:    reflect.TypeOf(([]*ConfigDetail)(nil)),
-	common.TypeAgentGROUP:      reflect.TypeOf(([]*AgentGroup)(nil)),
-	common.TypeCommand:         reflect.TypeOf(([]*Command)(nil)),
-}
diff --git a/config_server/service/proto/agent.pb.go b/config_server/service/proto/agent.pb.go
deleted file mode 100644
index 7205f9e339..0000000000
--- a/config_server/service/proto/agent.pb.go
+++ /dev/null
@@ -1,1473 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.28.1
-// 	protoc        v3.6.1
-// source: agent.proto
-
-package configserver_proto
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	reflect "reflect"
-	sync "sync"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// Define Config's type
-type ConfigType int32
-
-const (
-	ConfigType_PIPELINE_CONFIG ConfigType = 0
-	ConfigType_AGENT_CONFIG    ConfigType = 1
-)
-
-// Enum value maps for ConfigType.
-var (
-	ConfigType_name = map[int32]string{
-		0: "PIPELINE_CONFIG",
-		1: "AGENT_CONFIG",
-	}
-	ConfigType_value = map[string]int32{
-		"PIPELINE_CONFIG": 0,
-		"AGENT_CONFIG":    1,
-	}
-)
-
-func (x ConfigType) Enum() *ConfigType {
-	p := new(ConfigType)
-	*p = x
-	return p
-}
-
-func (x ConfigType) String() string {
-	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (ConfigType) Descriptor() protoreflect.EnumDescriptor {
-	return file_agent_proto_enumTypes[0].Descriptor()
-}
-
-func (ConfigType) Type() protoreflect.EnumType {
-	return &file_agent_proto_enumTypes[0]
-}
-
-func (x ConfigType) Number() protoreflect.EnumNumber {
-	return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Use ConfigType.Descriptor instead.
-func (ConfigType) EnumDescriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{0}
-}
-
-// Define Config's update status
-type CheckStatus int32
-
-const (
-	CheckStatus_NEW      CheckStatus = 0
-	CheckStatus_DELETED  CheckStatus = 1
-	CheckStatus_MODIFIED CheckStatus = 2
-)
-
-// Enum value maps for CheckStatus.
-var (
-	CheckStatus_name = map[int32]string{
-		0: "NEW",
-		1: "DELETED",
-		2: "MODIFIED",
-	}
-	CheckStatus_value = map[string]int32{
-		"NEW":      0,
-		"DELETED":  1,
-		"MODIFIED": 2,
-	}
-)
-
-func (x CheckStatus) Enum() *CheckStatus {
-	p := new(CheckStatus)
-	*p = x
-	return p
-}
-
-func (x CheckStatus) String() string {
-	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (CheckStatus) Descriptor() protoreflect.EnumDescriptor {
-	return file_agent_proto_enumTypes[1].Descriptor()
-}
-
-func (CheckStatus) Type() protoreflect.EnumType {
-	return &file_agent_proto_enumTypes[1]
-}
-
-func (x CheckStatus) Number() protoreflect.EnumNumber {
-	return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Use CheckStatus.Descriptor instead.
-func (CheckStatus) EnumDescriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{1}
-}
-
-// Define response code
-type RespCode int32
-
-const (
-	RespCode_ACCEPT                RespCode = 0
-	RespCode_INVALID_PARAMETER     RespCode = 1
-	RespCode_INTERNAL_SERVER_ERROR RespCode = 2
-)
-
-// Enum value maps for RespCode.
-var (
-	RespCode_name = map[int32]string{
-		0: "ACCEPT",
-		1: "INVALID_PARAMETER",
-		2: "INTERNAL_SERVER_ERROR",
-	}
-	RespCode_value = map[string]int32{
-		"ACCEPT":                0,
-		"INVALID_PARAMETER":     1,
-		"INTERNAL_SERVER_ERROR": 2,
-	}
-)
-
-func (x RespCode) Enum() *RespCode {
-	p := new(RespCode)
-	*p = x
-	return p
-}
-
-func (x RespCode) String() string {
-	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (RespCode) Descriptor() protoreflect.EnumDescriptor {
-	return file_agent_proto_enumTypes[2].Descriptor()
-}
-
-func (RespCode) Type() protoreflect.EnumType {
-	return &file_agent_proto_enumTypes[2]
-}
-
-func (x RespCode) Number() protoreflect.EnumNumber {
-	return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Use RespCode.Descriptor instead.
-func (RespCode) EnumDescriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{2}
-}
-
-// Define the Config information carried in the request
-type ConfigInfo struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Type    ConfigType `protobuf:"varint,1,opt,name=type,proto3,enum=configserver.proto.ConfigType" json:"type,omitempty"` // Required, Config's type
-	Name    string     `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`                                     // Required, Config's unique identification
-	Version int64      `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"`                              // Required, Config's version number
-	Context string     `protobuf:"bytes,4,opt,name=context,proto3" json:"context,omitempty"`                               // Config's context
-}
-
-func (x *ConfigInfo) Reset() {
-	*x = ConfigInfo{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[0]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *ConfigInfo) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*ConfigInfo) ProtoMessage() {}
-
-func (x *ConfigInfo) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_proto_msgTypes[0]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use ConfigInfo.ProtoReflect.Descriptor instead.
-func (*ConfigInfo) Descriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *ConfigInfo) GetType() ConfigType {
-	if x != nil {
-		return x.Type
-	}
-	return ConfigType_PIPELINE_CONFIG
-}
-
-func (x *ConfigInfo) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *ConfigInfo) GetVersion() int64 {
-	if x != nil {
-		return x.Version
-	}
-	return 0
-}
-
-func (x *ConfigInfo) GetContext() string {
-	if x != nil {
-		return x.Context
-	}
-	return ""
-}
-
-// Define the result of checking the Config update status
-type ConfigCheckResult struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Type        ConfigType  `protobuf:"varint,1,opt,name=type,proto3,enum=configserver.proto.ConfigType" json:"type,omitempty"`                                   // Required, Config's type
-	Name        string      `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`                                                                       // Required, Config's unique identification
-	OldVersion  int64       `protobuf:"varint,3,opt,name=old_version,json=oldVersion,proto3" json:"old_version,omitempty"`                                        // Required, Config's current version number
-	NewVersion  int64       `protobuf:"varint,4,opt,name=new_version,json=newVersion,proto3" json:"new_version,omitempty"`                                        // Required, Config's latest version number
-	Context     string      `protobuf:"bytes,5,opt,name=context,proto3" json:"context,omitempty"`                                                                 // Config's context
-	CheckStatus CheckStatus `protobuf:"varint,6,opt,name=check_status,json=checkStatus,proto3,enum=configserver.proto.CheckStatus" json:"check_status,omitempty"` // Required, Config's update status
-}
-
-func (x *ConfigCheckResult) Reset() {
-	*x = ConfigCheckResult{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[1]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *ConfigCheckResult) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*ConfigCheckResult) ProtoMessage() {}
-
-func (x *ConfigCheckResult) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_proto_msgTypes[1]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use ConfigCheckResult.ProtoReflect.Descriptor instead.
-func (*ConfigCheckResult) Descriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *ConfigCheckResult) GetType() ConfigType {
-	if x != nil {
-		return x.Type
-	}
-	return ConfigType_PIPELINE_CONFIG
-}
-
-func (x *ConfigCheckResult) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *ConfigCheckResult) GetOldVersion() int64 {
-	if x != nil {
-		return x.OldVersion
-	}
-	return 0
-}
-
-func (x *ConfigCheckResult) GetNewVersion() int64 {
-	if x != nil {
-		return x.NewVersion
-	}
-	return 0
-}
-
-func (x *ConfigCheckResult) GetContext() string {
-	if x != nil {
-		return x.Context
-	}
-	return ""
-}
-
-func (x *ConfigCheckResult) GetCheckStatus() CheckStatus {
-	if x != nil {
-		return x.CheckStatus
-	}
-	return CheckStatus_NEW
-}
-
-// Define Config's detail
-type ConfigDetail struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Type    ConfigType `protobuf:"varint,1,opt,name=type,proto3,enum=configserver.proto.ConfigType" json:"type,omitempty"` // Required, Config's type
-	Name    string     `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`                                     // Required, Config's unique identification
-	Version int64      `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"`                              // Required, Config's version number
-	Context string     `protobuf:"bytes,4,opt,name=context,proto3" json:"context,omitempty"`                               // Config's context
-	Detail  string     `protobuf:"bytes,5,opt,name=detail,proto3" json:"detail,omitempty"`                                 // Required, Config's detail
-}
-
-func (x *ConfigDetail) Reset() {
-	*x = ConfigDetail{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[2]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *ConfigDetail) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*ConfigDetail) ProtoMessage() {}
-
-func (x *ConfigDetail) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_proto_msgTypes[2]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use ConfigDetail.ProtoReflect.Descriptor instead.
-func (*ConfigDetail) Descriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{2}
-}
-
-func (x *ConfigDetail) GetType() ConfigType {
-	if x != nil {
-		return x.Type
-	}
-	return ConfigType_PIPELINE_CONFIG
-}
-
-func (x *ConfigDetail) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *ConfigDetail) GetVersion() int64 {
-	if x != nil {
-		return x.Version
-	}
-	return 0
-}
-
-func (x *ConfigDetail) GetContext() string {
-	if x != nil {
-		return x.Context
-	}
-	return ""
-}
-
-func (x *ConfigDetail) GetDetail() string {
-	if x != nil {
-		return x.Detail
-	}
-	return ""
-}
-
-// Define Agent's basic attributes
-type AgentAttributes struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Version  string            `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`                                                                                         // Agent's version
-	Category string            `protobuf:"bytes,2,opt,name=category,proto3" json:"category,omitempty"`                                                                                       // Agent's type(used to distinguish AGENT_CONFIG)
-	Ip       string            `protobuf:"bytes,3,opt,name=ip,proto3" json:"ip,omitempty"`                                                                                                   // Agent's ip
-	Hostname string            `protobuf:"bytes,4,opt,name=hostname,proto3" json:"hostname,omitempty"`                                                                                       // Agent's hostname
-	Region   string            `protobuf:"bytes,5,opt,name=region,proto3" json:"region,omitempty"`                                                                                           // Agent's region
-	Zone     string            `protobuf:"bytes,6,opt,name=zone,proto3" json:"zone,omitempty"`                                                                                               // Agent's zone
-	Extras   map[string]string `protobuf:"bytes,100,rep,name=extras,proto3" json:"extras,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Agent's other attributes
-}
-
-func (x *AgentAttributes) Reset() {
-	*x = AgentAttributes{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[3]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *AgentAttributes) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*AgentAttributes) ProtoMessage() {}
-
-func (x *AgentAttributes) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_proto_msgTypes[3]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use AgentAttributes.ProtoReflect.Descriptor instead.
-func (*AgentAttributes) Descriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{3}
-}
-
-func (x *AgentAttributes) GetVersion() string {
-	if x != nil {
-		return x.Version
-	}
-	return ""
-}
-
-func (x *AgentAttributes) GetCategory() string {
-	if x != nil {
-		return x.Category
-	}
-	return ""
-}
-
-func (x *AgentAttributes) GetIp() string {
-	if x != nil {
-		return x.Ip
-	}
-	return ""
-}
-
-func (x *AgentAttributes) GetHostname() string {
-	if x != nil {
-		return x.Hostname
-	}
-	return ""
-}
-
-func (x *AgentAttributes) GetRegion() string {
-	if x != nil {
-		return x.Region
-	}
-	return ""
-}
-
-func (x *AgentAttributes) GetZone() string {
-	if x != nil {
-		return x.Zone
-	}
-	return ""
-}
-
-func (x *AgentAttributes) GetExtras() map[string]string {
-	if x != nil {
-		return x.Extras
-	}
-	return nil
-}
-
-// Define command
-type Command struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Type string            `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`                                                                                         // Required, Command type
-	Name string            `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`                                                                                         // Required, Command name
-	Id   string            `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"`                                                                                             // Required, Command id
-	Args map[string]string `protobuf:"bytes,4,rep,name=args,proto3" json:"args,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Command's parameter arrays
-}
-
-func (x *Command) Reset() {
-	*x = Command{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[4]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *Command) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Command) ProtoMessage() {}
-
-func (x *Command) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_proto_msgTypes[4]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use Command.ProtoReflect.Descriptor instead.
-func (*Command) Descriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{4}
-}
-
-func (x *Command) GetType() string {
-	if x != nil {
-		return x.Type
-	}
-	return ""
-}
-
-func (x *Command) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *Command) GetId() string {
-	if x != nil {
-		return x.Id
-	}
-	return ""
-}
-
-func (x *Command) GetArgs() map[string]string {
-	if x != nil {
-		return x.Args
-	}
-	return nil
-}
-
-// Agent sends requests to the ConfigServer to send heartbeats, get config updates and receive commands.
-type HeartBeatRequest struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	RequestId       string           `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
-	AgentId         string           `protobuf:"bytes,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`                         // Required, Agent's unique identification
-	AgentType       string           `protobuf:"bytes,3,opt,name=agent_type,json=agentType,proto3" json:"agent_type,omitempty"`                   // Required, Agent's type(ilogtail, ..)
-	Attributes      *AgentAttributes `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"`                                  // Agent's basic attributes
-	Tags            []string         `protobuf:"bytes,5,rep,name=tags,proto3" json:"tags,omitempty"`                                              // Agent's tags
-	RunningStatus   string           `protobuf:"bytes,6,opt,name=running_status,json=runningStatus,proto3" json:"running_status,omitempty"`       // Required, Agent's running status
-	StartupTime     int64            `protobuf:"varint,7,opt,name=startup_time,json=startupTime,proto3" json:"startup_time,omitempty"`            // Required, Agent's startup time
-	Interval        int32            `protobuf:"varint,8,opt,name=interval,proto3" json:"interval,omitempty"`                                     // Agent's heartbeat interval
-	PipelineConfigs []*ConfigInfo    `protobuf:"bytes,9,rep,name=pipeline_configs,json=pipelineConfigs,proto3" json:"pipeline_configs,omitempty"` // Information about the current PIPELINE_CONFIG held by the Agent
-	AgentConfigs    []*ConfigInfo    `protobuf:"bytes,10,rep,name=agent_configs,json=agentConfigs,proto3" json:"agent_configs,omitempty"`         // Information about the current AGENT_CONFIG held by the Agent
-}
-
-func (x *HeartBeatRequest) Reset() {
-	*x = HeartBeatRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[5]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *HeartBeatRequest) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*HeartBeatRequest) ProtoMessage() {}
-
-func (x *HeartBeatRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_proto_msgTypes[5]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use HeartBeatRequest.ProtoReflect.Descriptor instead.
-func (*HeartBeatRequest) Descriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{5}
-}
-
-func (x *HeartBeatRequest) GetRequestId() string {
-	if x != nil {
-		return x.RequestId
-	}
-	return ""
-}
-
-func (x *HeartBeatRequest) GetAgentId() string {
-	if x != nil {
-		return x.AgentId
-	}
-	return ""
-}
-
-func (x *HeartBeatRequest) GetAgentType() string {
-	if x != nil {
-		return x.AgentType
-	}
-	return ""
-}
-
-func (x *HeartBeatRequest) GetAttributes() *AgentAttributes {
-	if x != nil {
-		return x.Attributes
-	}
-	return nil
-}
-
-func (x *HeartBeatRequest) GetTags() []string {
-	if x != nil {
-		return x.Tags
-	}
-	return nil
-}
-
-func (x *HeartBeatRequest) GetRunningStatus() string {
-	if x != nil {
-		return x.RunningStatus
-	}
-	return ""
-}
-
-func (x *HeartBeatRequest) GetStartupTime() int64 {
-	if x != nil {
-		return x.StartupTime
-	}
-	return 0
-}
-
-func (x *HeartBeatRequest) GetInterval() int32 {
-	if x != nil {
-		return x.Interval
-	}
-	return 0
-}
-
-func (x *HeartBeatRequest) GetPipelineConfigs() []*ConfigInfo {
-	if x != nil {
-		return x.PipelineConfigs
-	}
-	return nil
-}
-
-func (x *HeartBeatRequest) GetAgentConfigs() []*ConfigInfo {
-	if x != nil {
-		return x.AgentConfigs
-	}
-	return nil
-}
-
-// ConfigServer's response to Agent's heartbeats
-type HeartBeatResponse struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	RequestId            string               `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
-	Code                 RespCode             `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message              string               `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
-	PipelineCheckResults []*ConfigCheckResult `protobuf:"bytes,4,rep,name=pipeline_check_results,json=pipelineCheckResults,proto3" json:"pipeline_check_results,omitempty"` // Agent's PIPELINE_CONFIG update status
-	AgentCheckResults    []*ConfigCheckResult `protobuf:"bytes,5,rep,name=agent_check_results,json=agentCheckResults,proto3" json:"agent_check_results,omitempty"`          // Agent's AGENT_CONFIG update status
-	CustomCommands       []*Command           `protobuf:"bytes,6,rep,name=custom_commands,json=customCommands,proto3" json:"custom_commands,omitempty"`                     // Agent received commands
-}
-
-func (x *HeartBeatResponse) Reset() {
-	*x = HeartBeatResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[6]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *HeartBeatResponse) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*HeartBeatResponse) ProtoMessage() {}
-
-func (x *HeartBeatResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_proto_msgTypes[6]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use HeartBeatResponse.ProtoReflect.Descriptor instead.
-func (*HeartBeatResponse) Descriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{6}
-}
-
-func (x *HeartBeatResponse) GetRequestId() string {
-	if x != nil {
-		return x.RequestId
-	}
-	return ""
-}
-
-func (x *HeartBeatResponse) GetCode() RespCode {
-	if x != nil {
-		return x.Code
-	}
-	return RespCode_ACCEPT
-}
-
-func (x *HeartBeatResponse) GetMessage() string {
-	if x != nil {
-		return x.Message
-	}
-	return ""
-}
-
-func (x *HeartBeatResponse) GetPipelineCheckResults() []*ConfigCheckResult {
-	if x != nil {
-		return x.PipelineCheckResults
-	}
-	return nil
-}
-
-func (x *HeartBeatResponse) GetAgentCheckResults() []*ConfigCheckResult {
-	if x != nil {
-		return x.AgentCheckResults
-	}
-	return nil
-}
-
-func (x *HeartBeatResponse) GetCustomCommands() []*Command {
-	if x != nil {
-		return x.CustomCommands
-	}
-	return nil
-}
-
-// API: /Agent/FetchPipelineConfig/
-// Agent request to ConfigServer, pulling details of the PIPELINE_CONFIG
-type FetchPipelineConfigRequest struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	RequestId  string        `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
-	AgentId    string        `protobuf:"bytes,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`          // Required, Agent's unique identification
-	ReqConfigs []*ConfigInfo `protobuf:"bytes,3,rep,name=req_configs,json=reqConfigs,proto3" json:"req_configs,omitempty"` // PIPELINE_CONFIGs that Agent requires for full information
-}
-
-func (x *FetchPipelineConfigRequest) Reset() {
-	*x = FetchPipelineConfigRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[7]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *FetchPipelineConfigRequest) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*FetchPipelineConfigRequest) ProtoMessage() {}
-
-func (x *FetchPipelineConfigRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_proto_msgTypes[7]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use FetchPipelineConfigRequest.ProtoReflect.Descriptor instead.
-func (*FetchPipelineConfigRequest) Descriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{7}
-}
-
-func (x *FetchPipelineConfigRequest) GetRequestId() string {
-	if x != nil {
-		return x.RequestId
-	}
-	return ""
-}
-
-func (x *FetchPipelineConfigRequest) GetAgentId() string {
-	if x != nil {
-		return x.AgentId
-	}
-	return ""
-}
-
-func (x *FetchPipelineConfigRequest) GetReqConfigs() []*ConfigInfo {
-	if x != nil {
-		return x.ReqConfigs
-	}
-	return nil
-}
-
-// ConfigServer response to Agent's request
-type FetchPipelineConfigResponse struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	RequestId     string          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
-	Code          RespCode        `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message       string          `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
-	ConfigDetails []*ConfigDetail `protobuf:"bytes,4,rep,name=config_details,json=configDetails,proto3" json:"config_details,omitempty"` // PIPELINE_CONFIGs' detail
-}
-
-func (x *FetchPipelineConfigResponse) Reset() {
-	*x = FetchPipelineConfigResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[8]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *FetchPipelineConfigResponse) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*FetchPipelineConfigResponse) ProtoMessage() {}
-
-func (x *FetchPipelineConfigResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_proto_msgTypes[8]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use FetchPipelineConfigResponse.ProtoReflect.Descriptor instead.
-func (*FetchPipelineConfigResponse) Descriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{8}
-}
-
-func (x *FetchPipelineConfigResponse) GetRequestId() string {
-	if x != nil {
-		return x.RequestId
-	}
-	return ""
-}
-
-func (x *FetchPipelineConfigResponse) GetCode() RespCode {
-	if x != nil {
-		return x.Code
-	}
-	return RespCode_ACCEPT
-}
-
-func (x *FetchPipelineConfigResponse) GetMessage() string {
-	if x != nil {
-		return x.Message
-	}
-	return ""
-}
-
-func (x *FetchPipelineConfigResponse) GetConfigDetails() []*ConfigDetail {
-	if x != nil {
-		return x.ConfigDetails
-	}
-	return nil
-}
-
-// API: /Agent/FetchAgentConfig/
-// Agent request to ConfigServer, pulling details of the AGENT_CONFIG
-type FetchAgentConfigRequest struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	RequestId  string           `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
-	AgentId    string           `protobuf:"bytes,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`          // Required, Agent's unique identification
-	Attributes *AgentAttributes `protobuf:"bytes,3,opt,name=attributes,proto3" json:"attributes,omitempty"`                   // Required, Agent's basic attributes
-	ReqConfigs []*ConfigInfo    `protobuf:"bytes,4,rep,name=req_configs,json=reqConfigs,proto3" json:"req_configs,omitempty"` // AGENT_CONFIGs that Agent requires for full information
-}
-
-func (x *FetchAgentConfigRequest) Reset() {
-	*x = FetchAgentConfigRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[9]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *FetchAgentConfigRequest) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*FetchAgentConfigRequest) ProtoMessage() {}
-
-func (x *FetchAgentConfigRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_proto_msgTypes[9]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use FetchAgentConfigRequest.ProtoReflect.Descriptor instead.
-func (*FetchAgentConfigRequest) Descriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{9}
-}
-
-func (x *FetchAgentConfigRequest) GetRequestId() string {
-	if x != nil {
-		return x.RequestId
-	}
-	return ""
-}
-
-func (x *FetchAgentConfigRequest) GetAgentId() string {
-	if x != nil {
-		return x.AgentId
-	}
-	return ""
-}
-
-func (x *FetchAgentConfigRequest) GetAttributes() *AgentAttributes {
-	if x != nil {
-		return x.Attributes
-	}
-	return nil
-}
-
-func (x *FetchAgentConfigRequest) GetReqConfigs() []*ConfigInfo {
-	if x != nil {
-		return x.ReqConfigs
-	}
-	return nil
-}
-
-// ConfigServer response to Agent's request
-type FetchAgentConfigResponse struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	RequestId     string          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
-	Code          RespCode        `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
-	Message       string          `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
-	ConfigDetails []*ConfigDetail `protobuf:"bytes,4,rep,name=config_details,json=configDetails,proto3" json:"config_details,omitempty"` // AGENT_CONFIGs' detail
-}
-
-func (x *FetchAgentConfigResponse) Reset() {
-	*x = FetchAgentConfigResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[10]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *FetchAgentConfigResponse) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*FetchAgentConfigResponse) ProtoMessage() {}
-
-func (x *FetchAgentConfigResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_agent_proto_msgTypes[10]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use FetchAgentConfigResponse.ProtoReflect.Descriptor instead.
-func (*FetchAgentConfigResponse) Descriptor() ([]byte, []int) {
-	return file_agent_proto_rawDescGZIP(), []int{10}
-}
-
-func (x *FetchAgentConfigResponse) GetRequestId() string {
-	if x != nil {
-		return x.RequestId
-	}
-	return ""
-}
-
-func (x *FetchAgentConfigResponse) GetCode() RespCode {
-	if x != nil {
-		return x.Code
-	}
-	return RespCode_ACCEPT
-}
-
-func (x *FetchAgentConfigResponse) GetMessage() string {
-	if x != nil {
-		return x.Message
-	}
-	return ""
-}
-
-func (x *FetchAgentConfigResponse) GetConfigDetails() []*ConfigDetail {
-	if x != nil {
-		return x.ConfigDetails
-	}
-	return nil
-}
-
-var File_agent_proto protoreflect.FileDescriptor
-
-var file_agent_proto_rawDesc = []byte{
-	0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x22, 0x88, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f,
-	0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e,
-	0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04,
-	0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,
-	0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
-	0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0xfb, 0x01, 0x0a,
-	0x11, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75,
-	0x6c, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
-	0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x79, 0x70, 0x65,
-	0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x6c,
-	0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
-	0x0a, 0x6f, 0x6c, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6e,
-	0x65, 0x77, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03,
-	0x52, 0x0a, 0x6e, 0x65, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07,
-	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63,
-	0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x42, 0x0a, 0x0c, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f,
-	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0b, 0x63,
-	0x68, 0x65, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xa2, 0x01, 0x0a, 0x0c, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x32, 0x0a, 0x04, 0x74,
-	0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12,
-	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
-	0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a,
-	0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
-	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69,
-	0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22,
-	0xa3, 0x02, 0x0a, 0x0f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
-	0x74, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a,
-	0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73,
-	0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73,
-	0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18,
-	0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a,
-	0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x7a, 0x6f, 0x6e,
-	0x65, 0x12, 0x47, 0x0a, 0x06, 0x65, 0x78, 0x74, 0x72, 0x61, 0x73, 0x18, 0x64, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72,
-	0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x73, 0x45, 0x6e, 0x74,
-	0x72, 0x79, 0x52, 0x06, 0x65, 0x78, 0x74, 0x72, 0x61, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x45, 0x78,
-	0x74, 0x72, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
-	0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
-	0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb5, 0x01, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
-	0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x04, 0x61, 0x72, 0x67,
-	0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6d,
-	0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x72, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04,
-	0x61, 0x72, 0x67, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x41, 0x72, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72,
-	0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
-	0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xba, 0x03,
-	0x0a, 0x10, 0x48, 0x65, 0x61, 0x72, 0x74, 0x42, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
-	0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a,
-	0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x61,
-	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62,
-	0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73,
-	0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04,
-	0x74, 0x61, 0x67, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x5f,
-	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x75,
-	0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73,
-	0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28,
-	0x03, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1a,
-	0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05,
-	0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x49, 0x0a, 0x10, 0x70, 0x69,
-	0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x09,
-	0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72,
-	0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x43, 0x0a, 0x0d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x61, 0x67,
-	0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0xf8, 0x02, 0x0a, 0x11, 0x48,
-	0x65, 0x61, 0x72, 0x74, 0x42, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12,
-	0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e,
-	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64,
-	0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x5b, 0x0a, 0x16, 0x70,
-	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x72, 0x65,
-	0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75,
-	0x6c, 0x74, 0x52, 0x14, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x68, 0x65, 0x63,
-	0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x55, 0x0a, 0x13, 0x61, 0x67, 0x65, 0x6e,
-	0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18,
-	0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65,
-	0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x11, 0x61, 0x67,
-	0x65, 0x6e, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12,
-	0x44, 0x0a, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
-	0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f,
-	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d,
-	0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x97, 0x01, 0x0a, 0x1a, 0x46, 0x65, 0x74, 0x63, 0x68, 0x50,
-	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
-	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x3f,
-	0x0a, 0x0b, 0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x03, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76,
-	0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49,
-	0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x72, 0x65, 0x71, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22,
-	0xd1, 0x01, 0x0a, 0x1b, 0x46, 0x65, 0x74, 0x63, 0x68, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
-	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x30,
-	0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65,
-	0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x47, 0x0a, 0x0e, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03,
-	0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65,
-	0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65,
-	0x74, 0x61, 0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
-	0x69, 0x6c, 0x73, 0x22, 0xd9, 0x01, 0x0a, 0x17, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x67, 0x65,
-	0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x19,
-	0x0a, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x43, 0x0a, 0x0a, 0x61, 0x74, 0x74,
-	0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e,
-	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
-	0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x3f,
-	0x0a, 0x0b, 0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x04, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76,
-	0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49,
-	0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x72, 0x65, 0x71, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22,
-	0xce, 0x01, 0x0a, 0x18, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63,
-	0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52,
-	0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a,
-	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
-	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x47, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
-	0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69,
-	0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73,
-	0x2a, 0x33, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x13,
-	0x0a, 0x0f, 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49,
-	0x47, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x47, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4e,
-	0x46, 0x49, 0x47, 0x10, 0x01, 0x2a, 0x31, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74,
-	0x61, 0x74, 0x75, 0x73, 0x12, 0x07, 0x0a, 0x03, 0x4e, 0x45, 0x57, 0x10, 0x00, 0x12, 0x0b, 0x0a,
-	0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x4f,
-	0x44, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x48, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70,
-	0x43, 0x6f, 0x64, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, 0x00,
-	0x12, 0x15, 0x0a, 0x11, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x50, 0x41, 0x52, 0x41,
-	0x4d, 0x45, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x4e, 0x54, 0x45, 0x52,
-	0x4e, 0x41, 0x4c, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52,
-	0x10, 0x02, 0x42, 0x16, 0x5a, 0x14, 0x2e, 0x3b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65,
-	0x72, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x33,
-}
-
-var (
-	file_agent_proto_rawDescOnce sync.Once
-	file_agent_proto_rawDescData = file_agent_proto_rawDesc
-)
-
-func file_agent_proto_rawDescGZIP() []byte {
-	file_agent_proto_rawDescOnce.Do(func() {
-		file_agent_proto_rawDescData = protoimpl.X.CompressGZIP(file_agent_proto_rawDescData)
-	})
-	return file_agent_proto_rawDescData
-}
-
-var file_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
-var file_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
-var file_agent_proto_goTypes = []interface{}{
-	(ConfigType)(0),                     // 0: configserver.proto.ConfigType
-	(CheckStatus)(0),                    // 1: configserver.proto.CheckStatus
-	(RespCode)(0),                       // 2: configserver.proto.RespCode
-	(*ConfigInfo)(nil),                  // 3: configserver.proto.ConfigInfo
-	(*ConfigCheckResult)(nil),           // 4: configserver.proto.ConfigCheckResult
-	(*ConfigDetail)(nil),                // 5: configserver.proto.ConfigDetail
-	(*AgentAttributes)(nil),             // 6: configserver.proto.AgentAttributes
-	(*Command)(nil),                     // 7: configserver.proto.Command
-	(*HeartBeatRequest)(nil),            // 8: configserver.proto.HeartBeatRequest
-	(*HeartBeatResponse)(nil),           // 9: configserver.proto.HeartBeatResponse
-	(*FetchPipelineConfigRequest)(nil),  // 10: configserver.proto.FetchPipelineConfigRequest
-	(*FetchPipelineConfigResponse)(nil), // 11: configserver.proto.FetchPipelineConfigResponse
-	(*FetchAgentConfigRequest)(nil),     // 12: configserver.proto.FetchAgentConfigRequest
-	(*FetchAgentConfigResponse)(nil),    // 13: configserver.proto.FetchAgentConfigResponse
-	nil,                                 // 14: configserver.proto.AgentAttributes.ExtrasEntry
-	nil,                                 // 15: configserver.proto.Command.ArgsEntry
-}
-var file_agent_proto_depIdxs = []int32{
-	0,  // 0: configserver.proto.ConfigInfo.type:type_name -> configserver.proto.ConfigType
-	0,  // 1: configserver.proto.ConfigCheckResult.type:type_name -> configserver.proto.ConfigType
-	1,  // 2: configserver.proto.ConfigCheckResult.check_status:type_name -> configserver.proto.CheckStatus
-	0,  // 3: configserver.proto.ConfigDetail.type:type_name -> configserver.proto.ConfigType
-	14, // 4: configserver.proto.AgentAttributes.extras:type_name -> configserver.proto.AgentAttributes.ExtrasEntry
-	15, // 5: configserver.proto.Command.args:type_name -> configserver.proto.Command.ArgsEntry
-	6,  // 6: configserver.proto.HeartBeatRequest.attributes:type_name -> configserver.proto.AgentAttributes
-	3,  // 7: configserver.proto.HeartBeatRequest.pipeline_configs:type_name -> configserver.proto.ConfigInfo
-	3,  // 8: configserver.proto.HeartBeatRequest.agent_configs:type_name -> configserver.proto.ConfigInfo
-	2,  // 9: configserver.proto.HeartBeatResponse.code:type_name -> configserver.proto.RespCode
-	4,  // 10: configserver.proto.HeartBeatResponse.pipeline_check_results:type_name -> configserver.proto.ConfigCheckResult
-	4,  // 11: configserver.proto.HeartBeatResponse.agent_check_results:type_name -> configserver.proto.ConfigCheckResult
-	7,  // 12: configserver.proto.HeartBeatResponse.custom_commands:type_name -> configserver.proto.Command
-	3,  // 13: configserver.proto.FetchPipelineConfigRequest.req_configs:type_name -> configserver.proto.ConfigInfo
-	2,  // 14: configserver.proto.FetchPipelineConfigResponse.code:type_name -> configserver.proto.RespCode
-	5,  // 15: configserver.proto.FetchPipelineConfigResponse.config_details:type_name -> configserver.proto.ConfigDetail
-	6,  // 16: configserver.proto.FetchAgentConfigRequest.attributes:type_name -> configserver.proto.AgentAttributes
-	3,  // 17: configserver.proto.FetchAgentConfigRequest.req_configs:type_name -> configserver.proto.ConfigInfo
-	2,  // 18: configserver.proto.FetchAgentConfigResponse.code:type_name -> configserver.proto.RespCode
-	5,  // 19: configserver.proto.FetchAgentConfigResponse.config_details:type_name -> configserver.proto.ConfigDetail
-	20, // [20:20] is the sub-list for method output_type
-	20, // [20:20] is the sub-list for method input_type
-	20, // [20:20] is the sub-list for extension type_name
-	20, // [20:20] is the sub-list for extension extendee
-	0,  // [0:20] is the sub-list for field type_name
-}
-
-func init() { file_agent_proto_init() }
-func file_agent_proto_init() {
-	if File_agent_proto != nil {
-		return
-	}
-	if !protoimpl.UnsafeEnabled {
-		file_agent_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ConfigInfo); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ConfigCheckResult); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ConfigDetail); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*AgentAttributes); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Command); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*HeartBeatRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*HeartBeatResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*FetchPipelineConfigRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*FetchPipelineConfigResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*FetchAgentConfigRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*FetchAgentConfigResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-	}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_agent_proto_rawDesc,
-			NumEnums:      3,
-			NumMessages:   13,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_agent_proto_goTypes,
-		DependencyIndexes: file_agent_proto_depIdxs,
-		EnumInfos:         file_agent_proto_enumTypes,
-		MessageInfos:      file_agent_proto_msgTypes,
-	}.Build()
-	File_agent_proto = out.File
-	file_agent_proto_rawDesc = nil
-	file_agent_proto_goTypes = nil
-	file_agent_proto_depIdxs = nil
-}
diff --git a/config_server/service/router/router.go b/config_server/service/router/router.go
deleted file mode 100644
index c01fde50e5..0000000000
--- a/config_server/service/router/router.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package router
-
-import (
-	"github.com/gin-gonic/gin"
-
-	"config-server/interface/agent"
-	"config-server/interface/user"
-	"config-server/setting"
-)
-
-func InitRouter() {
-	router := gin.Default()
-
-	InitUserRouter(router)
-	InitAgentRouter(router)
-
-	err := router.Run(setting.GetSetting().IP + ":" + setting.GetSetting().Port)
-	if err != nil {
-		panic(err)
-	}
-}
-
-func InitUserRouter(router *gin.Engine) {
-	userGroup := router.Group("/User")
-	{
-		userGroup.POST("/CreateAgentGroup", user.CreateAgentGroup)
-		userGroup.PUT("/UpdateAgentGroup", user.UpdateAgentGroup)
-		userGroup.DELETE("/DeleteAgentGroup", user.DeleteAgentGroup)
-		userGroup.POST("/GetAgentGroup", user.GetAgentGroup)
-		userGroup.POST("/ListAgentGroups", user.ListAgentGroups)
-
-		userGroup.POST("/CreateConfig", user.CreateConfig)
-		userGroup.PUT("/UpdateConfig", user.UpdateConfig)
-		userGroup.DELETE("/DeleteConfig", user.DeleteConfig)
-		userGroup.POST("/GetConfig", user.GetConfig)
-		userGroup.POST("/ListConfigs", user.ListConfigs)
-
-		userGroup.PUT("/ApplyConfigToAgentGroup", user.ApplyConfigToAgentGroup)
-		userGroup.DELETE("/RemoveConfigFromAgentGroup", user.RemoveConfigFromAgentGroup)
-		userGroup.POST("/GetAppliedConfigsForAgentGroup", user.GetAppliedConfigsForAgentGroup)
-		userGroup.POST("/GetAppliedAgentGroups", user.GetAppliedAgentGroups)
-		userGroup.POST("/ListAgents", user.ListAgents)
-	}
-}
-
-func InitAgentRouter(router *gin.Engine) {
-	agentGroup := router.Group("/Agent")
-	{
-		agentGroup.POST("/HeartBeat", agent.HeartBeat)
-
-		agentGroup.POST("/FetchPipelineConfig", agent.FetchPipelineConfig)
-		agentGroup.POST("/FetchAgentConfig", agent.FetchAgentConfig)
-	}
-}
diff --git a/config_server/service/service.go b/config_server/service/service.go
deleted file mode 100644
index 3b2541a95a..0000000000
--- a/config_server/service/service.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
-	"config-server/router"
-	"config-server/store"
-)
-
-func main() {
-	defer store.GetStore().Close()
-	router.InitRouter()
-}
diff --git a/config_server/service/setting/mysql-setting.json b/config_server/service/setting/mysql-setting.json
deleted file mode 100644
index 233e2c4eb7..0000000000
--- a/config_server/service/setting/mysql-setting.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-    "ip":"127.0.0.1",
-    "store_mode": "gorm",
-    "port": "8899",
-    "db_path": "./DB",
-    "driver": "mysql",
-    "dsn": "ilogtail:123456@tcp(127.0.0.1:3306)/ilogtail_config_server?charset=utf8&parseTime=True&loc=Local",
-    "auto_migrate_schema": true,
-    "agent_update_interval": 1,
-    "config_sync_interval": 3
-}
diff --git a/config_server/service/setting/setting.go b/config_server/service/setting/setting.go
deleted file mode 100644
index 20f779eda4..0000000000
--- a/config_server/service/setting/setting.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package setting
-
-import (
-	"log"
-	"reflect"
-
-	"config-server/common"
-)
-
-type Setting struct {
-	IP                  string `json:"ip"`                    // default: "127.0.0.1"
-	StoreMode           string `json:"store_mode"`            // support "leveldb", "gorm"
-	Port                string `json:"port"`                  // default: "8899"
-	DbPath              string `json:"db_path"`               // default: "./DB"
-	Driver              string `json:"driver"`                // support "mysql", "postgre", "sqlite", "sqlserver"
-	Dsn                 string `json:"dsn"`                   // gorm dsn
-	AutoMigrateSchema   bool   `json:"auto_migrate_schema"`   // auto migrate schema
-	AgentUpdateInterval int    `json:"agent_update_interval"` // default: 1s
-	ConfigSyncInterval  int    `json:"config_sync_interval"`  // default: 3s
-}
-
-var mySetting *Setting
-
-var settingFile = "./setting/setting.json"
-
-/*
-Create a singleton of setting
-*/
-func GetSetting() Setting {
-	return *mySetting
-}
-
-/*
-Use map to update setting.
-For example, if the value of map is {store_mode:"mysql"},
-this function will change "mySetting's StoreMode" to "mysql".
-*/
-func UpdateSetting(tagMap map[string]interface{}) {
-	v := reflect.ValueOf(mySetting).Elem()
-	t := v.Type()
-
-	fieldNum := v.NumField()
-	for i := 0; i < fieldNum; i++ {
-		fieldInfo := t.Field(i)
-		tag := fieldInfo.Tag.Get("json")
-		if tag == "" {
-			continue
-		}
-		if value, ok := tagMap[tag]; ok {
-			if reflect.ValueOf(value).Type() == v.FieldByName(fieldInfo.Name).Type() {
-				v.FieldByName(fieldInfo.Name).Set(reflect.ValueOf(value))
-			}
-		}
-	}
-	err := common.WriteJSON(settingFile, mySetting)
-	if err != nil {
-		log.Println(err.Error())
-	}
-}
-
-func init() {
-	mySetting = new(Setting)
-	err := common.ReadJSON(settingFile, mySetting)
-	if err != nil {
-		panic(err)
-	}
-	if mySetting.IP == "" {
-		mySetting.IP = "127.0.0.1"
-	}
-	if mySetting.Port == "" {
-		mySetting.Port = "8899"
-	}
-	if mySetting.StoreMode == "" {
-		panic("Please set store mode")
-	}
-	if mySetting.StoreMode == "gorm" {
-		if mySetting.Driver == "" {
-			panic("Please set driver")
-		}
-		if mySetting.Dsn == "" {
-			panic("Please set dsn")
-		}
-	}
-	if mySetting.AgentUpdateInterval == 0 {
-		mySetting.AgentUpdateInterval = 1
-	}
-	if mySetting.ConfigSyncInterval == 0 {
-		mySetting.ConfigSyncInterval = 3
-	}
-}
diff --git a/config_server/service/setting/setting.json b/config_server/service/setting/setting.json
deleted file mode 100644
index cea005fc54..0000000000
--- a/config_server/service/setting/setting.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-    "ip":"127.0.0.1",
-    "store_mode": "leveldb",
-    "port": "8899",
-    "db_path": "./DB",
-    "agent_update_interval": 1,
-    "config_sync_interval": 3
-}
\ No newline at end of file
diff --git a/config_server/service/setting/sqlite-setting.json b/config_server/service/setting/sqlite-setting.json
deleted file mode 100644
index 981d45821a..0000000000
--- a/config_server/service/setting/sqlite-setting.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-    "ip":"127.0.0.1",
-    "store_mode": "gorm",
-    "port": "8899",
-    "driver": "sqlite",
-    "dsn": "sqlite.db",
-    "auto_migrate_schema": true,
-    "agent_update_interval": 1,
-    "config_sync_interval": 3
-}
diff --git a/config_server/service/store/gorm/gorm.go b/config_server/service/store/gorm/gorm.go
deleted file mode 100644
index b0145b60c7..0000000000
--- a/config_server/service/store/gorm/gorm.go
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2024 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package gorm
-
-import (
-	"errors"
-	"fmt"
-	"log"
-	"os"
-	"reflect"
-	"regexp"
-	"strings"
-	"time"
-
-	"config-server/model"
-	"config-server/setting"
-	database "config-server/store/interface_database"
-
-	"gorm.io/driver/mysql"
-	"gorm.io/driver/postgres"
-	"gorm.io/driver/sqlite"
-	"gorm.io/driver/sqlserver"
-	"gorm.io/gorm"
-	"gorm.io/gorm/logger"
-)
-
-type Store struct {
-	db *gorm.DB
-}
-
-func (s *Store) Connect() error {
-	slowLogger := logger.New(
-		log.New(os.Stdout, "\r\n", log.LstdFlags),
-		logger.Config{
-			SlowThreshold:             1 * time.Second,
-			LogLevel:                  logger.Warn,
-			IgnoreRecordNotFoundError: true,
-			Colorful:                  true,
-		},
-	)
-	option := gorm.Config{
-		Logger: slowLogger,
-	}
-	var db *gorm.DB
-	var err error
-	driver := setting.GetSetting().Driver
-	dsn := setting.GetSetting().Dsn
-	switch driver {
-	case "mysql":
-		db, err = gorm.Open(mysql.Open(dsn), &option)
-	case "postgre":
-		db, err = gorm.Open(postgres.Open(dsn), &option)
-	case "sqlite":
-		db, err = gorm.Open(sqlite.Open(dsn), &option)
-	case "sqlserver":
-		db, err = gorm.Open(sqlserver.Open(dsn), &option)
-	default:
-		return errors.New("wrong gorm driver: " + driver)
-	}
-	if err != nil {
-		return err
-	}
-	if setting.GetSetting().AutoMigrateSchema {
-		db.AutoMigrate(&model.AgentGroup{}, &model.ConfigDetail{}, &model.Agent{})
-	}
-	s.db = db
-	return nil
-}
-
-func (s *Store) GetMode() string {
-	return "gorm"
-}
-
-func (s *Store) Close() error {
-	db, err := s.db.DB()
-	if err != nil {
-		return err
-	}
-	return db.Close()
-}
-
-func (s *Store) Get(table string, entityKey string) (interface{}, error) {
-	model, pk, err := initModelAndPrimaryKey(table)
-	if err != nil {
-		return nil, err
-	}
-	err = s.db.Table(table).Where(fmt.Sprintf("%s = ?", pk), entityKey).Take(&model).Error
-	if err != nil {
-		return nil, err
-	}
-	return model, nil
-}
-
-func (s *Store) Add(table string, entityKey string, entity interface{}) error {
-	err := s.db.Table(table).Create(entity).Error
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func (s *Store) Update(table string, entityKey string, entity interface{}) error {
-	err := s.db.Table(table).Save(entity).Error
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func (s *Store) Has(table string, entityKey string) (bool, error) {
-	_, pk, err := initModelAndPrimaryKey(table)
-	if err != nil {
-		return false, err
-	}
-	var count int64
-	err = s.db.Table(table).Where(fmt.Sprintf("%s = ?", pk), entityKey).Limit(1).Count(&count).Error
-	if err != nil {
-		return false, err
-	}
-	return count > 0, nil
-}
-
-func (s *Store) Delete(table string, entityKey string) error {
-	_, pk, err := initModelAndPrimaryKey(table)
-	if err != nil {
-		return err
-	}
-	err = s.db.Table(table).Where(fmt.Sprintf("%s = ?", pk), entityKey).Delete(nil).Error
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func (s *Store) GetAll(table string) ([]interface{}, error) {
-	return s.GetWithPairs(table)
-}
-
-func (s *Store) GetWithPairs(table string, pairs ...interface{}) ([]interface{}, error) {
-	if len(pairs)%2 != 0 {
-		return nil, errors.New("params must be in pairs")
-	}
-
-	objectType, ok := model.ModelTypes[table]
-	if !ok {
-		return nil, errors.New("unsupported table: " + table)
-	}
-
-	objectsType := reflect.SliceOf(objectType.Elem())
-	objects := reflect.New(objectsType)
-
-	db := s.db.Table(table)
-	for i := 0; i < len(pairs); i += 2 {
-		column := camelCaseToSnakeCase(fmt.Sprintf("%v", pairs[i]))
-		value := pairs[i+1]
-		db = db.Where(fmt.Sprintf("%s = ?", column), value)
-	}
-
-	err := db.Find(objects.Interface()).Error
-	if err != nil {
-		return nil, err
-	}
-
-	objects = objects.Elem()
-
-	result := make([]interface{}, objects.Len())
-	for i := 0; i < objects.Len(); i++ {
-		result[i] = objects.Index(i).Interface()
-	}
-	return result, nil
-}
-
-func (s *Store) Count(table string) (int, error) {
-	var count int64
-	err := s.db.Table(table).Count(&count).Error
-	if err != nil {
-		return 0, err
-	}
-	return int(count), nil
-}
-
-func (s *Store) WriteBatch(batch *database.Batch) error {
-	tx := s.db.Begin()
-
-	for !batch.Empty() {
-		data := batch.Pop()
-		_, pk, err := initModelAndPrimaryKey(data.Table)
-		if err != nil {
-			tx.Rollback()
-			return err
-		}
-		if data.Opt == database.OptDelete {
-			err = tx.Table(data.Table).Where(fmt.Sprintf("%s = ?", pk), data.Key).Delete(nil).Error
-			if err != nil {
-				tx.Rollback()
-				return err
-			}
-		} else if data.Opt == database.OptAdd || data.Opt == database.OptUpdate {
-			isExist, err := s.Has(data.Table, data.Key)
-			if err != nil {
-				tx.Rollback()
-				return err
-			}
-			if isExist {
-				err = tx.Table(data.Table).Save(data.Value).Error
-			} else {
-				err = tx.Table(data.Table).Create(data.Value).Error
-			}
-			if err != nil {
-				tx.Rollback()
-				return err
-			}
-		}
-	}
-
-	if err := tx.Commit().Error; err != nil {
-		tx.Rollback()
-		return err
-	}
-	return nil
-}
-
-func initModelAndPrimaryKey(table string) (interface{}, string, error) {
-	m, ok := model.Models[table]
-	if !ok {
-		return nil, "", errors.New("unknown table: " + table)
-	}
-
-	ans := reflect.New(reflect.TypeOf(m).Elem()).Interface()
-	t := reflect.TypeOf(ans).Elem()
-	for i := 0; i < t.NumField(); i++ {
-		field := t.Field(i)
-		if tag := field.Tag.Get("gorm"); strings.Contains(tag, "primaryKey") {
-			column := getPrimaryKeyColumn(tag)
-			if column == "" {
-				return ans, field.Name, nil
-			}
-			return ans, column, nil
-		}
-	}
-	return ans, "", errors.New(table + " primary key not found")
-}
-
-func getPrimaryKeyColumn(s string) string {
-	splitStrings := strings.Split(s, ";")
-	for _, splitString := range splitStrings {
-		if strings.Contains(splitString, "column") {
-			columnParts := strings.Split(splitString, ":")
-			if len(columnParts) == 2 {
-				return columnParts[1]
-			}
-		}
-	}
-	return ""
-}
-
-func camelCaseToSnakeCase(s string) string {
-	r := regexp.MustCompile("([a-z0-9])([A-Z])")
-	snakeCase := r.ReplaceAllString(s, "${1}_${2}")
-	return strings.ToLower(snakeCase)
-}
diff --git a/config_server/service/store/interface_database/interface_database.go b/config_server/service/store/interface_database/interface_database.go
deleted file mode 100644
index ea6e2b7898..0000000000
--- a/config_server/service/store/interface_database/interface_database.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package database
-
-import (
-	"config-server/common"
-)
-
-/*
-Interface of store
-*/
-
-type Database interface {
-	Connect() error
-	GetMode() string // store mode
-	Close() error
-
-	Get(table string, entityKey string) (interface{}, error)
-	Add(table string, entityKey string, entity interface{}) error
-	Update(table string, entityKey string, entity interface{}) error
-	Has(table string, entityKey string) (bool, error)
-	Delete(table string, entityKey string) error
-	GetAll(table string) ([]interface{}, error)
-	Count(table string) (int, error)
-
-	WriteBatch(batch *Batch) error
-}
-
-// batch
-
-const (
-	OptAdd    string = "ADD"
-	OptDelete string = "DELETE"
-	OptUpdate string = "UPDATE"
-)
-
-type (
-	Data struct {
-		Opt   string
-		Table string
-		Key   string
-		Value interface{}
-	}
-
-	Batch struct {
-		datas common.Queue
-	}
-)
-
-func (b *Batch) Add(table string, entityKey string, entity interface{}) {
-	b.datas.Push(Data{OptAdd, table, entityKey, entity})
-}
-
-func (b *Batch) Update(table string, entityKey string, entity interface{}) {
-	b.datas.Push(Data{OptUpdate, table, entityKey, entity})
-}
-
-func (b *Batch) Delete(table string, entityKey string) {
-	b.datas.Push(Data{OptDelete, table, entityKey, nil})
-}
-
-func (b *Batch) Empty() bool {
-	return b.datas.Empty()
-}
-
-func (b *Batch) Pop() Data {
-	return b.datas.Pop().(Data)
-}
diff --git a/config_server/service/store/leveldb/leveldb.go b/config_server/service/store/leveldb/leveldb.go
deleted file mode 100644
index 1c558222e2..0000000000
--- a/config_server/service/store/leveldb/leveldb.go
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package leveldb
-
-import (
-	"encoding/json"
-	"log"
-
-	"github.com/syndtr/goleveldb/leveldb"
-
-	"config-server/common"
-	"config-server/model"
-	"config-server/setting"
-	database "config-server/store/interface_database"
-)
-
-var dbPath = []string{
-	common.TypeAgentAttributes,
-	common.TypeAgent,
-	common.TypeConfigDetail,
-	common.TypeAgentGROUP,
-	common.TypeCommand,
-}
-
-type Store struct {
-	db map[string]*leveldb.DB
-}
-
-func (l *Store) Connect() error {
-	l.db = make(map[string]*leveldb.DB)
-
-	var err error
-	for _, c := range dbPath {
-		l.db[c], err = leveldb.OpenFile(setting.GetSetting().DbPath+"/"+c, nil)
-		if err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-func (l *Store) GetMode() string {
-	return "leveldb"
-}
-
-func (l *Store) Close() error {
-	for _, db := range l.db {
-		err := db.Close()
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (l *Store) Get(table string, entityKey string) (interface{}, error) {
-	value, err := l.db[table].Get(generateKey(entityKey), nil)
-	if err != nil {
-		return nil, err
-	}
-	return parseValue(table, value), nil
-}
-
-func (l *Store) Add(table string, entityKey string, entity interface{}) error {
-	key := generateKey(entityKey)
-	value, err := generateValue(entity)
-	if err != nil {
-		return err
-	}
-
-	err = l.db[table].Put(key, value, nil)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func (l *Store) Update(table string, entityKey string, entity interface{}) error {
-	key := generateKey(entityKey)
-	value, err := generateValue(entity)
-	if err != nil {
-		return err
-	}
-
-	err = l.db[table].Put(key, value, nil)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func (l *Store) Has(table string, entityKey string) (bool, error) {
-	key := generateKey(entityKey)
-	ok, err := l.db[table].Has(key, nil)
-	if err != nil {
-		return false, err
-	}
-	return ok, nil
-}
-
-func (l *Store) Delete(table string, entityKey string) error {
-	key := generateKey(entityKey)
-	err := l.db[table].Delete(key, nil)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func (l *Store) GetAll(table string) ([]interface{}, error) {
-	ans := make([]interface{}, 0)
-
-	iter := l.db[table].NewIterator(nil, nil)
-	for iter.Next() {
-		ans = append(ans, parseValue(table, iter.Value()))
-	}
-
-	iter.Release()
-	err := iter.Error()
-	if err != nil {
-		return nil, err
-	}
-	return ans, nil
-}
-
-func (l *Store) Count(table string) (int, error) {
-	var ans int
-
-	iter := l.db[table].NewIterator(nil, nil)
-	for iter.Next() {
-		ans++
-	}
-
-	iter.Release()
-	err := iter.Error()
-	if err != nil {
-		return 0, err
-	}
-	return ans, nil
-}
-
-func (l *Store) WriteBatch(batch *database.Batch) error {
-	batchTemp := *batch
-	var leveldbBatch map[string]*leveldb.Batch = make(map[string]*leveldb.Batch)
-
-	for !batch.Empty() {
-		data := batch.Pop()
-		key := generateKey(data.Key)
-
-		if _, ok := leveldbBatch[data.Table]; !ok {
-			leveldbBatch[data.Table] = new(leveldb.Batch)
-		}
-
-		if data.Opt == database.OptDelete {
-			leveldbBatch[data.Table].Delete(key)
-		} else if data.Opt == database.OptAdd || data.Opt == database.OptUpdate {
-			value, err := generateValue(data.Value)
-			if err != nil {
-				*batch = batchTemp
-				return err
-			}
-			leveldbBatch[data.Table].Put(key, value)
-		}
-	}
-
-	for t, b := range leveldbBatch {
-		err := l.db[t].Write(b, nil)
-		if err != nil {
-			*batch = batchTemp
-			return err
-		}
-	}
-
-	return nil
-}
-
-func generateKey(key string) []byte {
-	return []byte(key)
-}
-
-func generateValue(entity interface{}) ([]byte, error) {
-	value, err := json.Marshal(entity)
-	if err != nil {
-		return nil, err
-	}
-	return value, nil
-}
-
-func parseValue(table string, data []byte) interface{} {
-	var ans interface{}
-	switch table {
-	case common.TypeAgentAttributes:
-		ans = new(model.AgentAttributes)
-	case common.TypeAgent:
-		ans = new(model.Agent)
-	case common.TypeConfigDetail:
-		ans = new(model.ConfigDetail)
-	case common.TypeAgentGROUP:
-		ans = new(model.AgentGroup)
-	case common.TypeCommand:
-		ans = new(model.Command)
-	}
-	err := json.Unmarshal(data, ans)
-	if err != nil {
-		log.Println(err.Error())
-	}
-	return ans
-}
diff --git a/config_server/service/store/store.go b/config_server/service/store/store.go
deleted file mode 100644
index a94ceb082a..0000000000
--- a/config_server/service/store/store.go
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package store
-
-import (
-	"config-server/setting"
-	"config-server/store/gorm"
-	database "config-server/store/interface_database"
-	"config-server/store/leveldb"
-)
-
-// Data in database
-
-/*
-Store Factory
-*/
-func newStore(storeType string) database.Database {
-	switch storeType {
-	case "gorm":
-		return new(gorm.Store)
-	case "leveldb":
-		return new(leveldb.Store)
-	default:
-		panic("Wrong store type.")
-	}
-}
-
-var myStore database.Database
-
-/*
-Create a singleton of store
-*/
-func GetStore() database.Database {
-	return myStore
-}
-
-// batch
-
-func CreateBacth() *database.Batch {
-	return new(database.Batch)
-}
-
-// init
-
-func init() {
-	myStore = newStore(setting.GetSetting().StoreMode)
-	err := myStore.Connect()
-	if err != nil {
-		panic(err)
-	}
-}
diff --git a/config_server/service/test/interface_test.go b/config_server/service/test/interface_test.go
deleted file mode 100644
index 388ec897e8..0000000000
--- a/config_server/service/test/interface_test.go
+++ /dev/null
@@ -1,1231 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package test
-
-import (
-	"fmt"
-	"testing"
-	"time"
-
-	"github.com/gin-gonic/gin"
-	. "github.com/smartystreets/goconvey/convey"
-
-	"config-server/common"
-	proto "config-server/proto"
-	"config-server/router"
-)
-
-func TestBaseAgentGroup(t *testing.T) {
-	gin.SetMode(gin.TestMode)
-	r := gin.New()
-	router.InitUserRouter(r)
-
-	var requestID int
-
-	Convey("Test delete AgentGroup.", t, func() {
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete default. ")
-		{
-			status, res := DeleteAgentGroup(r, "default", fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.BadRequest.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
-			So(res.Message, ShouldEqual, "Cannot delete agent group 'default'")
-
-			requestID++
-		}
-	})
-}
-
-func TestBaseConfig(t *testing.T) {
-	gin.SetMode(gin.TestMode)
-	r := gin.New()
-	router.InitUserRouter(r)
-
-	var requestID int
-
-	Convey("Test create Config.", t, func() {
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-1. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-1"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test"
-			config.Context = "Description for test"
-
-			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-1. ")
-		{
-			configName := "config-1"
-
-			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get config success")
-			So(res.ConfigDetail.Name, ShouldEqual, configName)
-			So(res.ConfigDetail.Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
-			So(res.ConfigDetail.Detail, ShouldEqual, "Detail for test")
-			So(res.ConfigDetail.Context, ShouldEqual, "Description for test")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-1. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-1"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test"
-			config.Context = "Description for test"
-
-			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.ConfigAlreadyExist.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
-			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s already exists.", config.Name))
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get all configs. ")
-		{
-			status, res := ListConfigs(r, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get config list success")
-			So(len(res.ConfigDetails), ShouldEqual, 1)
-			So(res.ConfigDetails[0].Name, ShouldEqual, "config-1")
-			So(res.ConfigDetails[0].Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
-			So(res.ConfigDetails[0].Detail, ShouldEqual, "Detail for test")
-			So(res.ConfigDetails[0].Context, ShouldEqual, "Description for test")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-2. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-2"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Context = "Description for test"
-
-			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.BadRequest.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
-			So(res.Message, ShouldEqual, fmt.Sprintf("Need parameter %s.", "Detail"))
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-2. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-2"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test"
-			config.Context = "Description for test"
-
-			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-2. ")
-		{
-			configName := "config-2"
-
-			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get config success")
-			So(res.ConfigDetail.Name, ShouldEqual, configName)
-			So(res.ConfigDetail.Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
-			So(res.ConfigDetail.Detail, ShouldEqual, "Detail for test")
-			So(res.ConfigDetail.Context, ShouldEqual, "Description for test")
-
-			requestID++
-		}
-	})
-
-	Convey("Test update Config.", t, func() {
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test update config-1. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-1"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test-updated"
-			config.Context = "Description for test-updated"
-
-			status, res := UpdateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Update config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-1. ")
-		{
-			configName := "config-1"
-
-			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get config success")
-			So(res.ConfigDetail.Name, ShouldEqual, configName)
-			So(res.ConfigDetail.Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
-			So(res.ConfigDetail.Detail, ShouldEqual, "Detail for test-updated")
-			So(res.ConfigDetail.Context, ShouldEqual, "Description for test-updated")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test update config-2. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-2"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test-updated"
-			config.Context = "Description for test-updated"
-
-			status, res := UpdateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Update config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-2. ")
-		{
-			configName := "config-2"
-
-			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get config success")
-			So(res.ConfigDetail.Name, ShouldEqual, configName)
-			So(res.ConfigDetail.Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
-			So(res.ConfigDetail.Detail, ShouldEqual, "Detail for test-updated")
-			So(res.ConfigDetail.Context, ShouldEqual, "Description for test-updated")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test update config-3. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-3"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test-updated"
-			config.Context = "Description for test-updated"
-
-			status, res := UpdateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.ConfigNotExist.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
-			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s doesn't exist.", config.Name))
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get all configs. ")
-		{
-			status, res := ListConfigs(r, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get config list success")
-			So(len(res.ConfigDetails), ShouldEqual, 2)
-			So(res.ConfigDetails[0].Name, ShouldEqual, "config-1")
-			So(res.ConfigDetails[0].Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
-			So(res.ConfigDetails[0].Detail, ShouldEqual, "Detail for test-updated")
-			So(res.ConfigDetails[0].Context, ShouldEqual, "Description for test-updated")
-			So(res.ConfigDetails[1].Name, ShouldEqual, "config-2")
-			So(res.ConfigDetails[1].Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
-			So(res.ConfigDetails[1].Detail, ShouldEqual, "Detail for test-updated")
-			So(res.ConfigDetails[1].Context, ShouldEqual, "Description for test-updated")
-
-			requestID++
-		}
-	})
-
-	Convey("Test delete Config.", t, func() {
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-1. ")
-		{
-			configName := "config-1"
-
-			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Delete config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-1. ")
-		{
-			configName := "config-1"
-
-			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.ConfigNotExist.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
-			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s doesn't exist.", configName))
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-1. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-1"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test"
-			config.Context = "Description for test"
-
-			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-1. ")
-		{
-			configName := "config-1"
-
-			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get config success")
-			So(res.ConfigDetail.Name, ShouldEqual, configName)
-			So(res.ConfigDetail.Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
-			So(res.ConfigDetail.Detail, ShouldEqual, "Detail for test")
-			So(res.ConfigDetail.Context, ShouldEqual, "Description for test")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-1. ")
-		{
-			configName := "config-1"
-
-			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Delete config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-1. ")
-		{
-			configName := "config-1"
-
-			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.ConfigNotExist.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
-			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s doesn't exist.", configName))
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-2. ")
-		{
-			configName := "config-2"
-
-			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Delete config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-2. ")
-		{
-			configName := "config-2"
-
-			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.ConfigNotExist.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
-			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s doesn't exist.", configName))
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get all configs. ")
-		{
-			status, res := ListConfigs(r, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get config list success")
-			So(len(res.ConfigDetails), ShouldEqual, 0)
-
-			requestID++
-		}
-	})
-}
-
-func TestOperationsBetweenConfigAndAgentGroup(t *testing.T) {
-	gin.SetMode(gin.TestMode)
-	r := gin.New()
-	router.InitUserRouter(r)
-
-	var requestID int
-
-	Convey("Test apply.", t, func() {
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-1. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-1"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test"
-			config.Context = "Description for test"
-
-			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-2. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-2"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test"
-			config.Context = "Description for test"
-
-			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test apply config-1 to default. ")
-		{
-			configName := "config-1"
-			groupName := "default"
-
-			status, res := ApplyConfigToAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config to agent group success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get default's Configs. ")
-		{
-			groupName := "default"
-
-			status, res := GetAppliedConfigsForAgentGroup(r, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get agent group's applied configs success")
-			So(len(res.ConfigNames), ShouldEqual, 1)
-			So(res.ConfigNames[0], ShouldEqual, "config-1")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-1's AgentGroups. ")
-		{
-			configName := "config-1"
-
-			status, res := GetAppliedAgentGroups(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get group list success")
-			So(len(res.AgentGroupNames), ShouldEqual, 1)
-			So(res.AgentGroupNames[0], ShouldEqual, "default")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-3's AgentGroups. ")
-		{
-			configName := "config-3"
-
-			status, res := GetAppliedAgentGroups(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.ConfigNotExist.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
-			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s doesn't exist.", configName))
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test apply config-2 to default. ")
-		{
-			configName := "config-2"
-			groupName := "default"
-
-			status, res := ApplyConfigToAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config to agent group success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get default's Configs. ")
-		{
-			groupName := "default"
-
-			status, res := GetAppliedConfigsForAgentGroup(r, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get agent group's applied configs success")
-			So(len(res.ConfigNames), ShouldEqual, 2)
-			So(res.ConfigNames, ShouldContain, "config-1")
-			So(res.ConfigNames, ShouldContain, "config-2")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-1. ")
-		{
-			configName := "config-1"
-
-			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.InternalServerError.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_INTERNAL_SERVER_ERROR)
-			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s was applied to some agent groups, cannot be deleted.", configName))
-
-			requestID++
-		}
-	})
-
-	Convey("Test remove.", t, func() {
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-2. ")
-		{
-			configName := "config-2"
-
-			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.InternalServerError.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_INTERNAL_SERVER_ERROR)
-			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s was applied to some agent groups, cannot be deleted.", configName))
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test remove config-2 from default. ")
-		{
-			configName := "config-2"
-			groupName := "default"
-
-			status, res := RemoveConfigFromAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Remove config from agent group success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get default's Configs. ")
-		{
-			groupName := "default"
-
-			status, res := GetAppliedConfigsForAgentGroup(r, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get agent group's applied configs success")
-			So(len(res.ConfigNames), ShouldEqual, 1)
-			So(res.ConfigNames[0], ShouldEqual, "config-1")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-2. ")
-		{
-			configName := "config-2"
-
-			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Delete config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test remove config-1 from default. ")
-		{
-			configName := "config-1"
-			groupName := "default"
-
-			status, res := RemoveConfigFromAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Remove config from agent group success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get default's Configs. ")
-		{
-			groupName := "default"
-
-			status, res := GetAppliedConfigsForAgentGroup(r, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get agent group's applied configs success")
-			So(len(res.ConfigNames), ShouldEqual, 0)
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-1. ")
-		{
-			configName := "config-1"
-
-			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Delete config success")
-
-			requestID++
-		}
-	})
-}
-
-func TestAgentSendMessage(t *testing.T) {
-	gin.SetMode(gin.TestMode)
-	r := gin.New()
-	router.InitAgentRouter(r)
-	router.InitUserRouter(r)
-
-	var requestID int
-
-	Convey("Test Agent send message.", t, func() {
-		configInfos := make([]*proto.ConfigCheckResult, 0)
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test ilogtail-1 send Heartbeat. ")
-		{
-			agent := new(proto.Agent)
-			agent.AgentId = "ilogtail-1"
-			agent.Attributes = &proto.AgentAttributes{}
-			agent.RunningStatus = "good"
-			agent.StartupTime = 100
-
-			status, res := HeartBeat(r, agent, configInfos, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Send heartbeat successGet config update infos success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Sleep 1s. ")
-		{
-			time.Sleep(time.Second * 1)
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test ilogtail-2 send Heartbeat. ")
-		{
-			agent := new(proto.Agent)
-			agent.AgentId = "ilogtail-2"
-			agent.Attributes = &proto.AgentAttributes{}
-			agent.RunningStatus = "good"
-			agent.StartupTime = 200
-
-			status, res := HeartBeat(r, agent, configInfos, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Send heartbeat successGet config update infos success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Sleep 1s. ")
-		{
-			time.Sleep(time.Second * 1)
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test ilogtail-1 send Heartbeat. ")
-		{
-			agent := new(proto.Agent)
-			agent.AgentId = "ilogtail-1"
-			agent.Attributes = &proto.AgentAttributes{}
-			agent.RunningStatus = "good"
-			agent.StartupTime = 100
-
-			status, res := HeartBeat(r, agent, configInfos, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Send heartbeat successGet config update infos success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Sleep 2s, wait for writing agent info to store. ")
-		{
-			time.Sleep(time.Second * 2)
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get default's Agents. ")
-		{
-			groupName := "default"
-
-			status, res := ListAgents(r, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get agent list success")
-			So(len(res.Agents), ShouldEqual, 2)
-			requestID++
-		}
-	})
-}
-
-func TestAgentGetConfig(t *testing.T) {
-	gin.SetMode(gin.TestMode)
-	r := gin.New()
-	router.InitAgentRouter(r)
-	router.InitUserRouter(r)
-
-	var requestID int
-
-	Convey("Test Agent get config.", t, func() {
-		agent := new(proto.Agent)
-		agent.AgentId = "ilogtail-1"
-		agent.Attributes = &proto.AgentAttributes{}
-		agent.RunningStatus = "good"
-		agent.StartupTime = 100
-
-		configVersions := map[string]int64{}
-		configInfos := make([]*proto.ConfigCheckResult, 0)
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-1. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-1"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test"
-			config.Context = "Description for test"
-
-			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-2. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-2"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test"
-			config.Context = "Description for test"
-
-			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-3. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-3"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test"
-			config.Context = "Description for test"
-
-			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-4. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-4"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test"
-			config.Context = "Description for test"
-
-			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test apply config-1 to default. ")
-		{
-			configName := "config-1"
-			groupName := "default"
-
-			status, res := ApplyConfigToAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config to agent group success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test apply config-2 to default. ")
-		{
-			configName := "config-2"
-			groupName := "default"
-
-			status, res := ApplyConfigToAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config to agent group success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test apply config-3 to default. ")
-		{
-			configName := "config-3"
-			groupName := "default"
-
-			status, res := ApplyConfigToAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config to agent group success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Sleep 3s, wait for writing config info to store. ")
-		{
-			time.Sleep(time.Second * 3)
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test ilogtail-1 send Heartbeat. ")
-		{
-			status, res := HeartBeat(r, agent, configInfos, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Send heartbeat successGet config update infos success")
-			So(len(res.PipelineCheckResults), ShouldEqual, 3)
-			for _, info := range res.PipelineCheckResults {
-				configVersions[info.Name] = info.NewVersion
-				switch info.Name {
-				case "config-1":
-					So(info.CheckStatus, ShouldEqual, proto.CheckStatus_NEW)
-				case "config-2":
-					So(info.CheckStatus, ShouldEqual, proto.CheckStatus_NEW)
-				case "config-3":
-					So(info.CheckStatus, ShouldEqual, proto.CheckStatus_NEW)
-				}
-			}
-			configInfos = res.PipelineCheckResults
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test fetch ilogtail-1's configs. ")
-		{
-			status, res := FetchPipelineConfig(r, configInfos, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get Agent Config details success")
-			So(len(res.ConfigDetails), ShouldEqual, 3)
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test apply config-4 to default. ")
-		{
-			configName := "config-4"
-			groupName := "default"
-
-			status, res := ApplyConfigToAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Add config to agent group success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test remove config-1 from default. ")
-		{
-			configName := "config-1"
-			groupName := "default"
-
-			status, res := RemoveConfigFromAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Remove config from agent group success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test update config-2. ")
-		{
-			config := &proto.ConfigDetail{}
-			config.Name = "config-2"
-			config.Type = proto.ConfigType_PIPELINE_CONFIG
-			config.Detail = "Detail for test-updated"
-			config.Context = "Description for test-updated"
-
-			status, res := UpdateConfig(r, config, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Update config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Sleep 3s, wait for writing config info to store. ")
-		{
-			time.Sleep(time.Second * 3)
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test ilogtail-1 send Heartbeat. ")
-		{
-			status, res := HeartBeat(r, agent, configInfos, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Send heartbeat successGet config update infos success")
-			So(len(res.PipelineCheckResults), ShouldEqual, 3)
-			configVersions = map[string]int64{}
-			for _, info := range res.PipelineCheckResults {
-				configVersions[info.Name] = info.NewVersion
-				switch info.Name {
-				case "config-1":
-					So(info.CheckStatus, ShouldEqual, proto.CheckStatus_DELETED)
-				case "config-2":
-					So(info.CheckStatus, ShouldEqual, proto.CheckStatus_MODIFIED)
-				case "config-4":
-					So(info.CheckStatus, ShouldEqual, proto.CheckStatus_NEW)
-				}
-			}
-			configInfos = res.PipelineCheckResults
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test fetch ilogtail-1's configs. ")
-		{
-			status, res := FetchPipelineConfig(r, configInfos, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Get Agent Config details success")
-			So(len(res.ConfigDetails), ShouldEqual, 3)
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test remove config-2 from default. ")
-		{
-			configName := "config-2"
-			groupName := "default"
-
-			status, res := RemoveConfigFromAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Remove config from agent group success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test remove config-3 from default. ")
-		{
-			configName := "config-3"
-			groupName := "default"
-
-			status, res := RemoveConfigFromAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Remove config from agent group success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test remove config-4 from default. ")
-		{
-			configName := "config-4"
-			groupName := "default"
-
-			status, res := RemoveConfigFromAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Remove config from agent group success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-1. ")
-		{
-			configName := "config-1"
-
-			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Delete config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-2. ")
-		{
-			configName := "config-2"
-
-			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Delete config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-3. ")
-		{
-			configName := "config-3"
-
-			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Delete config success")
-
-			requestID++
-		}
-
-		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-4. ")
-		{
-			configName := "config-4"
-
-			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
-
-			// check
-			So(status, ShouldEqual, common.Accept.Status)
-			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
-			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
-			So(res.Message, ShouldEqual, "Delete config success")
-
-			requestID++
-		}
-	})
-}
diff --git a/config_server/service/test/request.go b/config_server/service/test/request.go
deleted file mode 100644
index 9f2e85d74e..0000000000
--- a/config_server/service/test/request.go
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package test
-
-import (
-	"bytes"
-	"io"
-	"net/http"
-	"net/http/httptest"
-
-	"github.com/gin-gonic/gin"
-	"google.golang.org/protobuf/proto"
-
-	configserverproto "config-server/proto"
-)
-
-func DeleteAgentGroup(r *gin.Engine, groupName string, requestID string) (int, *configserverproto.DeleteAgentGroupResponse) {
-	// data
-	reqBody := configserverproto.DeleteAgentGroupRequest{}
-	reqBody.RequestId = requestID
-	reqBody.GroupName = groupName
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("DELETE", "/User/DeleteAgentGroup", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.DeleteAgentGroupResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
-
-func CreateConfig(r *gin.Engine, config *configserverproto.ConfigDetail, requestID string) (int, *configserverproto.CreateConfigResponse) {
-	// data
-	reqBody := configserverproto.CreateConfigRequest{}
-	reqBody.RequestId = requestID
-	reqBody.ConfigDetail = config
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("POST", "/User/CreateConfig", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.CreateConfigResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
-
-func GetConfig(r *gin.Engine, configName string, requestID string) (int, *configserverproto.GetConfigResponse) {
-	// data
-	reqBody := configserverproto.GetConfigRequest{}
-	reqBody.RequestId = requestID
-	reqBody.ConfigName = configName
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("POST", "/User/GetConfig", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.GetConfigResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
-
-func UpdateConfig(r *gin.Engine, config *configserverproto.ConfigDetail, requestID string) (int, *configserverproto.UpdateConfigResponse) {
-	// data
-	reqBody := configserverproto.UpdateConfigRequest{}
-	reqBody.RequestId = requestID
-	reqBody.ConfigDetail = config
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("PUT", "/User/UpdateConfig", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.UpdateConfigResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
-
-func DeleteConfig(r *gin.Engine, configName string, requestID string) (int, *configserverproto.DeleteConfigResponse) {
-	// data
-	reqBody := configserverproto.DeleteConfigRequest{}
-	reqBody.RequestId = requestID
-	reqBody.ConfigName = configName
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("DELETE", "/User/DeleteConfig", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.DeleteConfigResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
-
-func ListConfigs(r *gin.Engine, requestID string) (int, *configserverproto.ListConfigsResponse) {
-	// data
-	reqBody := configserverproto.ListConfigsRequest{}
-	reqBody.RequestId = requestID
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("POST", "/User/ListConfigs", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.ListConfigsResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
-
-func ApplyConfigToAgentGroup(r *gin.Engine, configName string, groupName string, requestID string) (int, *configserverproto.ApplyConfigToAgentGroupResponse) {
-	// data
-	reqBody := configserverproto.ApplyConfigToAgentGroupRequest{}
-	reqBody.RequestId = requestID
-	reqBody.ConfigName = configName
-	reqBody.GroupName = groupName
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("PUT", "/User/ApplyConfigToAgentGroup", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.ApplyConfigToAgentGroupResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
-
-func RemoveConfigFromAgentGroup(r *gin.Engine, configName string, groupName string, requestID string) (int, *configserverproto.RemoveConfigFromAgentGroupResponse) {
-	// data
-	reqBody := configserverproto.RemoveConfigFromAgentGroupRequest{}
-	reqBody.RequestId = requestID
-	reqBody.ConfigName = configName
-	reqBody.GroupName = groupName
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("DELETE", "/User/RemoveConfigFromAgentGroup", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.RemoveConfigFromAgentGroupResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
-
-func GetAppliedConfigsForAgentGroup(r *gin.Engine, groupName string, requestID string) (int, *configserverproto.GetAppliedConfigsForAgentGroupResponse) {
-	// data
-	reqBody := configserverproto.GetAppliedConfigsForAgentGroupRequest{}
-	reqBody.RequestId = requestID
-	reqBody.GroupName = groupName
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("POST", "/User/GetAppliedConfigsForAgentGroup", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.GetAppliedConfigsForAgentGroupResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
-
-func GetAppliedAgentGroups(r *gin.Engine, configName string, requestID string) (int, *configserverproto.GetAppliedAgentGroupsResponse) {
-	// data
-	reqBody := configserverproto.GetAppliedAgentGroupsRequest{}
-	reqBody.RequestId = requestID
-	reqBody.ConfigName = configName
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("POST", "/User/GetAppliedAgentGroups", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.GetAppliedAgentGroupsResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
-
-func ListAgents(r *gin.Engine, groupName string, requestID string) (int, *configserverproto.ListAgentsResponse) {
-	// data
-	reqBody := configserverproto.ListAgentsRequest{}
-	reqBody.RequestId = requestID
-	reqBody.GroupName = groupName
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("POST", "/User/ListAgents", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.ListAgentsResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
-
-func HeartBeat(r *gin.Engine, agent *configserverproto.Agent, configInfos []*configserverproto.ConfigCheckResult, requestID string) (int, *configserverproto.HeartBeatResponse) {
-	// data
-	reqBody := configserverproto.HeartBeatRequest{}
-	reqBody.RequestId = requestID
-	reqBody.AgentId = agent.AgentId
-	reqBody.AgentType = agent.AgentType
-	reqBody.Attributes = agent.Attributes
-	reqBody.RunningStatus = agent.RunningStatus
-	reqBody.StartupTime = agent.StartupTime
-	reqBody.Tags = agent.Tags
-	pipelineConfigs := make([]*configserverproto.ConfigInfo, 0)
-	for _, c := range configInfos {
-		conf := new(configserverproto.ConfigInfo)
-		conf.Type = c.Type
-		conf.Name = c.Name
-		conf.Version = c.OldVersion
-		pipelineConfigs = append(pipelineConfigs, conf)
-	}
-	reqBody.PipelineConfigs = pipelineConfigs
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("POST", "/Agent/HeartBeat", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.HeartBeatResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
-
-func FetchPipelineConfig(r *gin.Engine, configInfos []*configserverproto.ConfigCheckResult, requestID string) (int, *configserverproto.FetchPipelineConfigResponse) {
-	// data
-	reqBody := configserverproto.FetchPipelineConfigRequest{}
-	reqBody.RequestId = requestID
-	reqBody.ReqConfigs = make([]*configserverproto.ConfigInfo, 0)
-	for _, c := range configInfos {
-		conf := new(configserverproto.ConfigInfo)
-		conf.Name = c.Name
-		conf.Context = c.Context
-		conf.Type = c.Type
-		conf.Version = c.NewVersion
-		reqBody.ReqConfigs = append(reqBody.ReqConfigs, conf)
-	}
-	reqBodyByte, _ := proto.Marshal(&reqBody)
-
-	// request
-	w := httptest.NewRecorder()
-	req, _ := http.NewRequest("POST", "/Agent/FetchPipelineConfig", bytes.NewBuffer(reqBodyByte))
-	r.ServeHTTP(w, req)
-
-	// response
-	res := w.Result()
-	resBodyByte, _ := io.ReadAll(res.Body)
-	resBody := new(configserverproto.FetchPipelineConfigResponse)
-	_ = proto.Unmarshal(resBodyByte, resBody)
-
-	return res.StatusCode, resBody
-}
diff --git a/config_server/service/test/setting/setting.json b/config_server/service/test/setting/setting.json
deleted file mode 100644
index e34bbfa186..0000000000
--- a/config_server/service/test/setting/setting.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ip":"127.0.0.1","store_mode":"leveldb","port":"8899","db_path":"./DB","agent_update_interval":1,"config_sync_interval":3}
\ No newline at end of file
diff --git a/config_server/service/test/setting_test.go b/config_server/service/test/setting_test.go
deleted file mode 100644
index 12b997cb7a..0000000000
--- a/config_server/service/test/setting_test.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package test
-
-import (
-	"testing"
-
-	. "github.com/smartystreets/goconvey/convey"
-
-	"config-server/setting"
-)
-
-func TestSetting(t *testing.T) {
-	Convey("Test load setting.", t, func() {
-		So(setting.GetSetting().StoreMode, ShouldEqual, "leveldb")
-	})
-
-	Convey("Test update setting.", t, func() {
-		So(setting.GetSetting().StoreMode, ShouldEqual, "leveldb")
-		setting.UpdateSetting(map[string]interface{}{"store_mode": "mysql"})
-		So(setting.GetSetting().StoreMode, ShouldEqual, "mysql")
-		setting.UpdateSetting(map[string]interface{}{"store_mode": "leveldb"})
-		So(setting.GetSetting().StoreMode, ShouldEqual, "leveldb")
-	})
-}
diff --git a/config_server/service/test/store_test.go b/config_server/service/test/store_test.go
deleted file mode 100644
index c63074e448..0000000000
--- a/config_server/service/test/store_test.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2022 iLogtail Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package test
-
-import (
-	"testing"
-
-	. "github.com/smartystreets/goconvey/convey"
-
-	"config-server/common"
-	"config-server/model"
-	"config-server/store"
-)
-
-func TestStore(t *testing.T) {
-	Convey("Test load store, check it's type.", t, func() {
-		So(store.GetStore().GetMode(), ShouldEqual, "leveldb")
-	})
-
-	Convey("Test store's CURD, take config as example.", t, func() {
-		s := store.GetStore()
-
-		Convey("First, add a config named config-test to store.", func() {
-			config := new(model.ConfigDetail)
-			config.Name = "config-test"
-			config.Type = "PIPELINE_CONFIG"
-			config.Detail = "test"
-			config.Version = 1
-			config.Context = ""
-			config.DelTag = false
-			s.Add(common.TypeConfigDetail, config.Name, config)
-
-			value, getErr := s.Get(common.TypeConfigDetail, "config-test")
-			So(getErr, ShouldBeNil)
-			So(value.(*model.ConfigDetail), ShouldResemble, &model.ConfigDetail{Name: "config-test", Type: "PIPELINE_CONFIG", Detail: "test", Version: 1, Context: "", DelTag: false})
-		})
-
-		Convey("Second, update config-test's content.", func() {
-			value, getErr := s.Get(common.TypeConfigDetail, "config-test")
-			So(getErr, ShouldBeNil)
-			config := value.(*model.ConfigDetail)
-			config.Context = "test"
-			s.Update(common.TypeConfigDetail, config.Name, config)
-
-			value, getErr = s.Get(common.TypeConfigDetail, "config-test")
-			So(getErr, ShouldBeNil)
-			So(value.(*model.ConfigDetail), ShouldResemble, &model.ConfigDetail{Name: "config-test", Type: "PIPELINE_CONFIG", Detail: "test", Version: 1, Context: "test", DelTag: false})
-		})
-
-		Convey("Third, delete config-test.", func() {
-			s.Delete(common.TypeConfigDetail, "config-test")
-			_, getErr := s.Get(common.TypeConfigDetail, "config-test")
-			So(getErr, ShouldNotBeNil)
-		})
-	})
-}

From ab9cbf50f95e6d3a8793e6126436e41b8dd73d76 Mon Sep 17 00:00:00 2001
From: Ww67652 <1749113286@qq.com>
Date: Mon, 30 Sep 2024 22:34:04 +0800
Subject: [PATCH 02/11] update: change directory structure

---
 config_server/service/.gitignore              |  2 +-
 .../{internal => }/common/api_error.go        |  0
 .../{internal => }/common/http_status.go      |  0
 .../service/{internal => }/common/log.go      |  0
 .../service/{internal => }/common/result.go   |  2 +-
 .../service/{internal => }/config/gorm.go     |  4 +--
 .../service/{internal => }/config/server.go   |  4 +--
 .../service/{internal => }/entity/agent.go    | 14 ++++----
 .../{internal => }/entity/agent_and_config.go |  2 +-
 .../{internal => }/entity/agent_group.go      |  2 +-
 .../service/{internal => }/entity/base.go     |  0
 .../service/{internal => }/entity/command.go  |  0
 .../service/{internal => }/entity/config.go   |  2 +-
 .../service/{internal => }/handler/agent.go   | 32 +++++++++----------
 .../{internal => }/handler/agent_group.go     |  6 ++--
 .../{internal => }/handler/instance_config.go |  6 ++--
 .../{internal => }/handler/pipeline_config.go |  6 ++--
 .../service/{internal => }/manager/agent.go   |  4 +--
 .../{internal => }/manager/agent_group.go     |  6 ++--
 .../manager/capability/agent.go               |  6 ++--
 .../manager/capability/common.go              |  0
 .../manager/capability/server.go              | 12 +++----
 .../service/{internal => }/manager/config.go  |  8 ++---
 .../{internal => }/manager/flag/request.go    |  6 ++--
 .../{internal => }/manager/flag/response.go   |  8 ++---
 .../{internal => }/protov2/agent.pb.go        |  0
 .../service/{internal => }/protov2/user.pb.go |  0
 .../{internal => }/repository/agent.go        |  6 ++--
 .../{internal => }/repository/agent_group.go  |  4 +--
 .../service/{internal => }/repository/base.go |  2 +-
 .../{internal => }/repository/config.go       |  4 +--
 .../repository/instance_config.go             |  4 +--
 .../repository/pipeline_config.go             |  4 +--
 .../service/{internal => }/router/router.go   |  2 +-
 .../{internal => }/router/router_test.go      |  4 +--
 .../service/{internal => }/service/agent.go   | 14 ++++----
 .../{internal => }/service/agent_group.go     | 28 ++++++++--------
 .../{internal => }/service/instance_config.go | 10 +++---
 .../{internal => }/service/pipeline_config.go | 10 +++---
 .../service/{internal => }/store/gorm.go      |  4 +--
 .../service/{internal => }/store/gorm_test.go |  0
 .../service/{internal => }/store/store.go     |  0
 .../{internal => }/utils/environment.go       |  0
 .../service/{internal => }/utils/json.go      |  0
 .../service/{internal => }/utils/list.go      |  0
 .../service/{internal => }/utils/str.go       |  0
 .../service/{internal => }/utils/task.go      |  0
 47 files changed, 114 insertions(+), 114 deletions(-)
 rename config_server/service/{internal => }/common/api_error.go (100%)
 rename config_server/service/{internal => }/common/http_status.go (100%)
 rename config_server/service/{internal => }/common/log.go (100%)
 rename config_server/service/{internal => }/common/result.go (92%)
 rename config_server/service/{internal => }/config/gorm.go (97%)
 rename config_server/service/{internal => }/config/server.go (92%)
 rename config_server/service/{internal => }/entity/agent.go (89%)
 rename config_server/service/{internal => }/entity/agent_and_config.go (98%)
 rename config_server/service/{internal => }/entity/agent_group.go (96%)
 rename config_server/service/{internal => }/entity/base.go (100%)
 rename config_server/service/{internal => }/entity/command.go (100%)
 rename config_server/service/{internal => }/entity/config.go (98%)
 rename config_server/service/{internal => }/handler/agent.go (84%)
 rename config_server/service/{internal => }/handler/agent_group.go (97%)
 rename config_server/service/{internal => }/handler/instance_config.go (98%)
 rename config_server/service/{internal => }/handler/pipeline_config.go (98%)
 rename config_server/service/{internal => }/manager/agent.go (94%)
 rename config_server/service/{internal => }/manager/agent_group.go (96%)
 rename config_server/service/{internal => }/manager/capability/agent.go (95%)
 rename config_server/service/{internal => }/manager/capability/common.go (100%)
 rename config_server/service/{internal => }/manager/capability/server.go (94%)
 rename config_server/service/{internal => }/manager/config.go (92%)
 rename config_server/service/{internal => }/manager/flag/request.go (91%)
 rename config_server/service/{internal => }/manager/flag/response.go (94%)
 rename config_server/service/{internal => }/protov2/agent.pb.go (100%)
 rename config_server/service/{internal => }/protov2/user.pb.go (100%)
 rename config_server/service/{internal => }/repository/agent.go (96%)
 rename config_server/service/{internal => }/repository/agent_group.go (97%)
 rename config_server/service/{internal => }/repository/base.go (97%)
 rename config_server/service/{internal => }/repository/config.go (96%)
 rename config_server/service/{internal => }/repository/instance_config.go (98%)
 rename config_server/service/{internal => }/repository/pipeline_config.go (98%)
 rename config_server/service/{internal => }/router/router.go (98%)
 rename config_server/service/{internal => }/router/router_test.go (96%)
 rename config_server/service/{internal => }/service/agent.go (95%)
 rename config_server/service/{internal => }/service/agent_group.go (73%)
 rename config_server/service/{internal => }/service/instance_config.go (96%)
 rename config_server/service/{internal => }/service/pipeline_config.go (96%)
 rename config_server/service/{internal => }/store/gorm.go (98%)
 rename config_server/service/{internal => }/store/gorm_test.go (100%)
 rename config_server/service/{internal => }/store/store.go (100%)
 rename config_server/service/{internal => }/utils/environment.go (100%)
 rename config_server/service/{internal => }/utils/json.go (100%)
 rename config_server/service/{internal => }/utils/list.go (100%)
 rename config_server/service/{internal => }/utils/str.go (100%)
 rename config_server/service/{internal => }/utils/task.go (100%)

diff --git a/config_server/service/.gitignore b/config_server/service/.gitignore
index eb9157e35b..2d5f70f38e 100644
--- a/config_server/service/.gitignore
+++ b/config_server/service/.gitignore
@@ -1,4 +1,4 @@
-internal/router/cmd
+router/cmd
 ConfigServer
 cmd/config/dev/*
 .idea
diff --git a/config_server/service/internal/common/api_error.go b/config_server/service/common/api_error.go
similarity index 100%
rename from config_server/service/internal/common/api_error.go
rename to config_server/service/common/api_error.go
diff --git a/config_server/service/internal/common/http_status.go b/config_server/service/common/http_status.go
similarity index 100%
rename from config_server/service/internal/common/http_status.go
rename to config_server/service/common/http_status.go
diff --git a/config_server/service/internal/common/log.go b/config_server/service/common/log.go
similarity index 100%
rename from config_server/service/internal/common/log.go
rename to config_server/service/common/log.go
diff --git a/config_server/service/internal/common/result.go b/config_server/service/common/result.go
similarity index 92%
rename from config_server/service/internal/common/result.go
rename to config_server/service/common/result.go
index 009a6dd47d..3ad4666ad2 100644
--- a/config_server/service/internal/common/result.go
+++ b/config_server/service/common/result.go
@@ -1,7 +1,7 @@
 package common
 
 import (
-	proto "config-server/internal/protov2"
+	proto "config-server/protov2"
 	"errors"
 )
 
diff --git a/config_server/service/internal/config/gorm.go b/config_server/service/config/gorm.go
similarity index 97%
rename from config_server/service/internal/config/gorm.go
rename to config_server/service/config/gorm.go
index a9d308535c..dc6d454e55 100644
--- a/config_server/service/internal/config/gorm.go
+++ b/config_server/service/config/gorm.go
@@ -1,8 +1,8 @@
 package config
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/utils"
+	"config-server/common"
+	"config-server/utils"
 	"fmt"
 	"gorm.io/driver/mysql"
 	"gorm.io/driver/postgres"
diff --git a/config_server/service/internal/config/server.go b/config_server/service/config/server.go
similarity index 92%
rename from config_server/service/internal/config/server.go
rename to config_server/service/config/server.go
index a01ab6351e..1cfb5d51b0 100644
--- a/config_server/service/internal/config/server.go
+++ b/config_server/service/config/server.go
@@ -1,8 +1,8 @@
 package config
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/utils"
+	"config-server/common"
+	"config-server/utils"
 	"fmt"
 	"log"
 	"path/filepath"
diff --git a/config_server/service/internal/entity/agent.go b/config_server/service/entity/agent.go
similarity index 89%
rename from config_server/service/internal/entity/agent.go
rename to config_server/service/entity/agent.go
index a51adf4158..1146034192 100644
--- a/config_server/service/internal/entity/agent.go
+++ b/config_server/service/entity/agent.go
@@ -1,7 +1,7 @@
 package entity
 
 import (
-	"config-server/internal/protov2"
+	proto "config-server/protov2"
 	"database/sql/driver"
 	"encoding/json"
 	"fmt"
@@ -14,8 +14,8 @@ type AgentAttributes struct {
 	Extras   map[string][]byte
 }
 
-func (a *AgentAttributes) Parse2Proto() *protov2.AgentAttributes {
-	protoAgentAttributes := new(protov2.AgentAttributes)
+func (a *AgentAttributes) Parse2Proto() *proto.AgentAttributes {
+	protoAgentAttributes := new(proto.AgentAttributes)
 	protoAgentAttributes.Version = a.Version
 	protoAgentAttributes.Ip = a.Ip
 	protoAgentAttributes.Hostname = a.Hostname
@@ -23,7 +23,7 @@ func (a *AgentAttributes) Parse2Proto() *protov2.AgentAttributes {
 	return protoAgentAttributes
 }
 
-func ParseProtoAgentAttributes2AgentAttributes(attributes *protov2.AgentAttributes) *AgentAttributes {
+func ParseProtoAgentAttributes2AgentAttributes(attributes *proto.AgentAttributes) *AgentAttributes {
 	agentAttributes := new(AgentAttributes)
 	agentAttributes.Version = attributes.Version
 	agentAttributes.Ip = attributes.Ip
@@ -72,8 +72,8 @@ type Agent struct {
 	LastHeartBeatTime int64
 }
 
-func (a Agent) Parse2Proto() *protov2.Agent {
-	protoAgent := new(protov2.Agent)
+func (a Agent) Parse2Proto() *proto.Agent {
+	protoAgent := new(proto.Agent)
 	protoAgent.Capabilities = a.Capabilities
 	protoAgent.InstanceId = []byte(a.InstanceId)
 	protoAgent.AgentType = a.AgentType
@@ -84,7 +84,7 @@ func (a Agent) Parse2Proto() *protov2.Agent {
 }
 
 // ParseHeartBeatRequest2BasicAgent transfer agent's basic info
-func ParseHeartBeatRequest2BasicAgent(req *protov2.HeartbeatRequest, lastHeartBeatTime int64) *Agent {
+func ParseHeartBeatRequest2BasicAgent(req *proto.HeartbeatRequest, lastHeartBeatTime int64) *Agent {
 	agent := new(Agent)
 	agent.SequenceNum = req.SequenceNum
 	agent.Capabilities = req.Capabilities
diff --git a/config_server/service/internal/entity/agent_and_config.go b/config_server/service/entity/agent_and_config.go
similarity index 98%
rename from config_server/service/internal/entity/agent_and_config.go
rename to config_server/service/entity/agent_and_config.go
index 46d4a8f5d3..db9c3e2971 100644
--- a/config_server/service/internal/entity/agent_and_config.go
+++ b/config_server/service/entity/agent_and_config.go
@@ -1,7 +1,7 @@
 package entity
 
 import (
-	proto "config-server/internal/protov2"
+	proto "config-server/protov2"
 )
 
 type AgentPipelineConfig struct {
diff --git a/config_server/service/internal/entity/agent_group.go b/config_server/service/entity/agent_group.go
similarity index 96%
rename from config_server/service/internal/entity/agent_group.go
rename to config_server/service/entity/agent_group.go
index 67a5895218..b54373639b 100644
--- a/config_server/service/internal/entity/agent_group.go
+++ b/config_server/service/entity/agent_group.go
@@ -1,7 +1,7 @@
 package entity
 
 import (
-	proto "config-server/internal/protov2"
+	proto "config-server/protov2"
 )
 
 const AgentGroupDefaultValue = "default"
diff --git a/config_server/service/internal/entity/base.go b/config_server/service/entity/base.go
similarity index 100%
rename from config_server/service/internal/entity/base.go
rename to config_server/service/entity/base.go
diff --git a/config_server/service/internal/entity/command.go b/config_server/service/entity/command.go
similarity index 100%
rename from config_server/service/internal/entity/command.go
rename to config_server/service/entity/command.go
diff --git a/config_server/service/internal/entity/config.go b/config_server/service/entity/config.go
similarity index 98%
rename from config_server/service/internal/entity/config.go
rename to config_server/service/entity/config.go
index b653c257ec..9c506ddfab 100644
--- a/config_server/service/internal/entity/config.go
+++ b/config_server/service/entity/config.go
@@ -1,7 +1,7 @@
 package entity
 
 import (
-	proto "config-server/internal/protov2"
+	proto "config-server/protov2"
 )
 
 type ConfigStatus int32
diff --git a/config_server/service/internal/handler/agent.go b/config_server/service/handler/agent.go
similarity index 84%
rename from config_server/service/internal/handler/agent.go
rename to config_server/service/handler/agent.go
index 2f90e1c947..d4defadf85 100644
--- a/config_server/service/internal/handler/agent.go
+++ b/config_server/service/handler/agent.go
@@ -1,10 +1,10 @@
 package handler
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/config"
-	proto "config-server/internal/protov2"
-	"config-server/internal/service"
+	"config-server/common"
+	"config-server/config"
+	"config-server/protov2"
+	"config-server/service"
 	"github.com/gin-gonic/gin"
 	"github.com/gin-gonic/gin/binding"
 )
@@ -14,8 +14,8 @@ func CheckAgentExist() {
 }
 
 func HeartBeat(c *gin.Context) {
-	request := &proto.HeartbeatRequest{}
-	response := &proto.HeartbeatResponse{}
+	request := &protov2.HeartbeatRequest{}
+	response := &protov2.HeartbeatResponse{}
 	var err error
 	defer func() {
 		response.CommonResponse = common.GenerateCommonResponse(err)
@@ -38,8 +38,8 @@ func HeartBeat(c *gin.Context) {
 }
 
 func FetchPipelineConfig(c *gin.Context) {
-	request := &proto.FetchConfigRequest{}
-	response := &proto.FetchConfigResponse{}
+	request := &protov2.FetchConfigRequest{}
+	response := &protov2.FetchConfigResponse{}
 	var err error
 	defer func() {
 		response.CommonResponse = common.GenerateCommonResponse(err)
@@ -62,8 +62,8 @@ func FetchPipelineConfig(c *gin.Context) {
 }
 
 func FetchInstanceConfig(c *gin.Context) {
-	request := &proto.FetchConfigRequest{}
-	response := &proto.FetchConfigResponse{}
+	request := &protov2.FetchConfigRequest{}
+	response := &protov2.FetchConfigResponse{}
 	var err error
 	defer func() {
 		response.CommonResponse = common.GenerateCommonResponse(err)
@@ -86,8 +86,8 @@ func FetchInstanceConfig(c *gin.Context) {
 }
 
 func ListAgentsInGroup(c *gin.Context) {
-	request := &proto.ListAgentsRequest{}
-	response := &proto.ListAgentsResponse{}
+	request := &protov2.ListAgentsRequest{}
+	response := &protov2.ListAgentsResponse{}
 	var err error
 	defer func() {
 		response.CommonResponse = common.GenerateCommonResponse(err)
@@ -110,8 +110,8 @@ func ListAgentsInGroup(c *gin.Context) {
 }
 
 func GetPipelineConfigStatusList(c *gin.Context) {
-	request := &proto.GetConfigStatusListRequest{}
-	response := &proto.GetConfigStatusListResponse{}
+	request := &protov2.GetConfigStatusListRequest{}
+	response := &protov2.GetConfigStatusListResponse{}
 	var err error
 	defer func() {
 		response.CommonResponse = common.GenerateCommonResponse(err)
@@ -134,8 +134,8 @@ func GetPipelineConfigStatusList(c *gin.Context) {
 }
 
 func GetInstanceConfigStatusList(c *gin.Context) {
-	request := &proto.GetConfigStatusListRequest{}
-	response := &proto.GetConfigStatusListResponse{}
+	request := &protov2.GetConfigStatusListRequest{}
+	response := &protov2.GetConfigStatusListResponse{}
 	var err error
 	defer func() {
 		response.CommonResponse = common.GenerateCommonResponse(err)
diff --git a/config_server/service/internal/handler/agent_group.go b/config_server/service/handler/agent_group.go
similarity index 97%
rename from config_server/service/internal/handler/agent_group.go
rename to config_server/service/handler/agent_group.go
index f20ea40388..06e32f8565 100644
--- a/config_server/service/internal/handler/agent_group.go
+++ b/config_server/service/handler/agent_group.go
@@ -1,9 +1,9 @@
 package handler
 
 import (
-	"config-server/internal/common"
-	proto "config-server/internal/protov2"
-	"config-server/internal/service"
+	"config-server/common"
+	proto "config-server/protov2"
+	"config-server/service"
 	"github.com/gin-gonic/gin"
 	"github.com/gin-gonic/gin/binding"
 )
diff --git a/config_server/service/internal/handler/instance_config.go b/config_server/service/handler/instance_config.go
similarity index 98%
rename from config_server/service/internal/handler/instance_config.go
rename to config_server/service/handler/instance_config.go
index 4a657bdd10..1be64a667d 100644
--- a/config_server/service/internal/handler/instance_config.go
+++ b/config_server/service/handler/instance_config.go
@@ -1,9 +1,9 @@
 package handler
 
 import (
-	"config-server/internal/common"
-	proto "config-server/internal/protov2"
-	"config-server/internal/service"
+	"config-server/common"
+	proto "config-server/protov2"
+	"config-server/service"
 	"github.com/gin-gonic/gin"
 	"github.com/gin-gonic/gin/binding"
 )
diff --git a/config_server/service/internal/handler/pipeline_config.go b/config_server/service/handler/pipeline_config.go
similarity index 98%
rename from config_server/service/internal/handler/pipeline_config.go
rename to config_server/service/handler/pipeline_config.go
index 6311fb101c..752ced81cc 100644
--- a/config_server/service/internal/handler/pipeline_config.go
+++ b/config_server/service/handler/pipeline_config.go
@@ -1,9 +1,9 @@
 package handler
 
 import (
-	"config-server/internal/common"
-	proto "config-server/internal/protov2"
-	"config-server/internal/service"
+	"config-server/common"
+	proto "config-server/protov2"
+	"config-server/service"
 	"github.com/gin-gonic/gin"
 	"github.com/gin-gonic/gin/binding"
 )
diff --git a/config_server/service/internal/manager/agent.go b/config_server/service/manager/agent.go
similarity index 94%
rename from config_server/service/internal/manager/agent.go
rename to config_server/service/manager/agent.go
index 14065dec3d..36bc5bbdbf 100644
--- a/config_server/service/internal/manager/agent.go
+++ b/config_server/service/manager/agent.go
@@ -1,8 +1,8 @@
 package manager
 
 import (
-	"config-server/internal/entity"
-	"config-server/internal/repository"
+	"config-server/entity"
+	"config-server/repository"
 	"log"
 	"time"
 )
diff --git a/config_server/service/internal/manager/agent_group.go b/config_server/service/manager/agent_group.go
similarity index 96%
rename from config_server/service/internal/manager/agent_group.go
rename to config_server/service/manager/agent_group.go
index 01f7af544b..553d3e339b 100644
--- a/config_server/service/internal/manager/agent_group.go
+++ b/config_server/service/manager/agent_group.go
@@ -1,9 +1,9 @@
 package manager
 
 import (
-	"config-server/internal/entity"
-	"config-server/internal/repository"
-	"config-server/internal/utils"
+	"config-server/entity"
+	"config-server/repository"
+	"config-server/utils"
 )
 
 func AddDefaultAgentGroup(agentTags []*entity.AgentGroup) []*entity.AgentGroup {
diff --git a/config_server/service/internal/manager/capability/agent.go b/config_server/service/manager/capability/agent.go
similarity index 95%
rename from config_server/service/internal/manager/capability/agent.go
rename to config_server/service/manager/capability/agent.go
index a51bbb392d..575e5ff97b 100644
--- a/config_server/service/internal/manager/capability/agent.go
+++ b/config_server/service/manager/capability/agent.go
@@ -1,9 +1,9 @@
 package capability
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/manager"
-	proto "config-server/internal/protov2"
+	"config-server/common"
+	"config-server/manager"
+	proto "config-server/protov2"
 	"log"
 )
 
diff --git a/config_server/service/internal/manager/capability/common.go b/config_server/service/manager/capability/common.go
similarity index 100%
rename from config_server/service/internal/manager/capability/common.go
rename to config_server/service/manager/capability/common.go
diff --git a/config_server/service/internal/manager/capability/server.go b/config_server/service/manager/capability/server.go
similarity index 94%
rename from config_server/service/internal/manager/capability/server.go
rename to config_server/service/manager/capability/server.go
index 02044bc83a..c2d6b1e30b 100644
--- a/config_server/service/internal/manager/capability/server.go
+++ b/config_server/service/manager/capability/server.go
@@ -1,12 +1,12 @@
 package capability
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/config"
-	"config-server/internal/entity"
-	"config-server/internal/manager"
-	proto "config-server/internal/protov2"
-	"config-server/internal/repository"
+	"config-server/common"
+	"config-server/config"
+	"config-server/entity"
+	"config-server/manager"
+	proto "config-server/protov2"
+	"config-server/repository"
 )
 
 type ServerAction struct {
diff --git a/config_server/service/internal/manager/config.go b/config_server/service/manager/config.go
similarity index 92%
rename from config_server/service/internal/manager/config.go
rename to config_server/service/manager/config.go
index c48949fd0b..05f2db9f65 100644
--- a/config_server/service/internal/manager/config.go
+++ b/config_server/service/manager/config.go
@@ -1,10 +1,10 @@
 package manager
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/entity"
-	proto "config-server/internal/protov2"
-	"config-server/internal/repository"
+	"config-server/common"
+	"config-server/entity"
+	proto "config-server/protov2"
+	"config-server/repository"
 )
 
 func CreateOrUpdateAgentInstanceConfigs(agentInstanceConfigs []*entity.AgentInstanceConfig) error {
diff --git a/config_server/service/internal/manager/flag/request.go b/config_server/service/manager/flag/request.go
similarity index 91%
rename from config_server/service/internal/manager/flag/request.go
rename to config_server/service/manager/flag/request.go
index cb674d28f0..9ed758338e 100644
--- a/config_server/service/internal/manager/flag/request.go
+++ b/config_server/service/manager/flag/request.go
@@ -1,9 +1,9 @@
 package flag
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/manager/capability"
-	proto "config-server/internal/protov2"
+	"config-server/common"
+	"config-server/manager/capability"
+	proto "config-server/protov2"
 )
 
 const (
diff --git a/config_server/service/internal/manager/flag/response.go b/config_server/service/manager/flag/response.go
similarity index 94%
rename from config_server/service/internal/manager/flag/response.go
rename to config_server/service/manager/flag/response.go
index 2b88a7f7ac..aaa4d7bf6a 100644
--- a/config_server/service/internal/manager/flag/response.go
+++ b/config_server/service/manager/flag/response.go
@@ -1,10 +1,10 @@
 package flag
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/config"
-	"config-server/internal/manager/capability"
-	proto "config-server/internal/protov2"
+	"config-server/common"
+	"config-server/config"
+	"config-server/manager/capability"
+	proto "config-server/protov2"
 )
 
 type ResponseAction struct {
diff --git a/config_server/service/internal/protov2/agent.pb.go b/config_server/service/protov2/agent.pb.go
similarity index 100%
rename from config_server/service/internal/protov2/agent.pb.go
rename to config_server/service/protov2/agent.pb.go
diff --git a/config_server/service/internal/protov2/user.pb.go b/config_server/service/protov2/user.pb.go
similarity index 100%
rename from config_server/service/internal/protov2/user.pb.go
rename to config_server/service/protov2/user.pb.go
diff --git a/config_server/service/internal/repository/agent.go b/config_server/service/repository/agent.go
similarity index 96%
rename from config_server/service/internal/repository/agent.go
rename to config_server/service/repository/agent.go
index 0bdf10a31b..1d63f77c0a 100644
--- a/config_server/service/internal/repository/agent.go
+++ b/config_server/service/repository/agent.go
@@ -1,9 +1,9 @@
 package repository
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/entity"
-	"config-server/internal/store"
+	"config-server/common"
+	"config-server/entity"
+	"config-server/store"
 	"gorm.io/gorm"
 )
 
diff --git a/config_server/service/internal/repository/agent_group.go b/config_server/service/repository/agent_group.go
similarity index 97%
rename from config_server/service/internal/repository/agent_group.go
rename to config_server/service/repository/agent_group.go
index cebbe95551..dae459c1c9 100644
--- a/config_server/service/internal/repository/agent_group.go
+++ b/config_server/service/repository/agent_group.go
@@ -1,8 +1,8 @@
 package repository
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/entity"
+	"config-server/common"
+	"config-server/entity"
 )
 
 func CreateAgentGroup(group *entity.AgentGroup) error {
diff --git a/config_server/service/internal/repository/base.go b/config_server/service/repository/base.go
similarity index 97%
rename from config_server/service/internal/repository/base.go
rename to config_server/service/repository/base.go
index 9d69bd6d49..7b619847d1 100644
--- a/config_server/service/internal/repository/base.go
+++ b/config_server/service/repository/base.go
@@ -1,7 +1,7 @@
 package repository
 
 import (
-	"config-server/internal/common"
+	"config-server/common"
 	"gorm.io/gorm/clause"
 )
 
diff --git a/config_server/service/internal/repository/config.go b/config_server/service/repository/config.go
similarity index 96%
rename from config_server/service/internal/repository/config.go
rename to config_server/service/repository/config.go
index f96ff2c24a..ab1dc9a12a 100644
--- a/config_server/service/internal/repository/config.go
+++ b/config_server/service/repository/config.go
@@ -1,8 +1,8 @@
 package repository
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/entity"
+	"config-server/common"
+	"config-server/entity"
 )
 
 func CreateOrUpdateAgentPipelineConfigs(conflictColumnNames []string, assignmentColumns []string, configs ...*entity.AgentPipelineConfig) error {
diff --git a/config_server/service/internal/repository/instance_config.go b/config_server/service/repository/instance_config.go
similarity index 98%
rename from config_server/service/internal/repository/instance_config.go
rename to config_server/service/repository/instance_config.go
index 0c54c68fcc..e9cfba66a5 100644
--- a/config_server/service/internal/repository/instance_config.go
+++ b/config_server/service/repository/instance_config.go
@@ -1,8 +1,8 @@
 package repository
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/entity"
+	"config-server/common"
+	"config-server/entity"
 )
 
 func CreateInstanceConfig(config *entity.InstanceConfig) error {
diff --git a/config_server/service/internal/repository/pipeline_config.go b/config_server/service/repository/pipeline_config.go
similarity index 98%
rename from config_server/service/internal/repository/pipeline_config.go
rename to config_server/service/repository/pipeline_config.go
index a0001bb8b9..a4fcd2200e 100644
--- a/config_server/service/internal/repository/pipeline_config.go
+++ b/config_server/service/repository/pipeline_config.go
@@ -1,8 +1,8 @@
 package repository
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/entity"
+	"config-server/common"
+	"config-server/entity"
 )
 
 func CreatePipelineConfig(config *entity.PipelineConfig) error {
diff --git a/config_server/service/internal/router/router.go b/config_server/service/router/router.go
similarity index 98%
rename from config_server/service/internal/router/router.go
rename to config_server/service/router/router.go
index 2d5ac3d3e0..2d1ffec5f8 100644
--- a/config_server/service/internal/router/router.go
+++ b/config_server/service/router/router.go
@@ -1,7 +1,7 @@
 package router
 
 import (
-	"config-server/internal/handler"
+	"config-server/handler"
 	"github.com/gin-gonic/gin"
 )
 
diff --git a/config_server/service/internal/router/router_test.go b/config_server/service/router/router_test.go
similarity index 96%
rename from config_server/service/internal/router/router_test.go
rename to config_server/service/router/router_test.go
index 13382ded05..e3bd46812f 100644
--- a/config_server/service/internal/router/router_test.go
+++ b/config_server/service/router/router_test.go
@@ -2,8 +2,8 @@ package router
 
 import (
 	"bytes"
-	"config-server/internal/config"
-	"config-server/internal/protov2"
+	"config-server/config"
+	"config-server/protov2"
 	"fmt"
 	"google.golang.org/protobuf/proto"
 	"io"
diff --git a/config_server/service/internal/service/agent.go b/config_server/service/service/agent.go
similarity index 95%
rename from config_server/service/internal/service/agent.go
rename to config_server/service/service/agent.go
index 62289a70e5..d2d68d703b 100644
--- a/config_server/service/internal/service/agent.go
+++ b/config_server/service/service/agent.go
@@ -1,13 +1,13 @@
 package service
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/entity"
-	"config-server/internal/manager"
-	"config-server/internal/manager/flag"
-	proto "config-server/internal/protov2"
-	"config-server/internal/repository"
-	"config-server/internal/utils"
+	"config-server/common"
+	"config-server/entity"
+	"config-server/manager"
+	"config-server/manager/flag"
+	proto "config-server/protov2"
+	"config-server/repository"
+	"config-server/utils"
 	"time"
 )
 
diff --git a/config_server/service/internal/service/agent_group.go b/config_server/service/service/agent_group.go
similarity index 73%
rename from config_server/service/internal/service/agent_group.go
rename to config_server/service/service/agent_group.go
index 42039717a6..ed01b45f59 100644
--- a/config_server/service/internal/service/agent_group.go
+++ b/config_server/service/service/agent_group.go
@@ -1,12 +1,12 @@
 package service
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/entity"
-	"config-server/internal/manager"
-	"config-server/internal/protov2"
-	"config-server/internal/repository"
-	"config-server/internal/utils"
+	"config-server/common"
+	"config-server/entity"
+	"config-server/manager"
+	proto "config-server/protov2"
+	"config-server/repository"
+	"config-server/utils"
 )
 
 // AppliedOrRemoveConfigForAgentGroup 定期检查在group中的agent与config的关系是否符合group与config的关系
@@ -22,7 +22,7 @@ func AppliedOrRemoveConfigForAgentGroup(timeLimit int64) {
 	})
 }
 
-func CreateAgentGroup(req *protov2.CreateAgentGroupRequest, res *protov2.CreateAgentGroupResponse) error {
+func CreateAgentGroup(req *proto.CreateAgentGroupRequest, res *proto.CreateAgentGroupResponse) error {
 	agentGroup := req.AgentGroup
 	if agentGroup == nil {
 		return common.ValidateErrorWithMsg("required field agentGroup could not be null")
@@ -36,7 +36,7 @@ func CreateAgentGroup(req *protov2.CreateAgentGroupRequest, res *protov2.CreateA
 	return common.SystemError(err)
 }
 
-func UpdateAgentGroup(req *protov2.UpdateAgentGroupRequest, res *protov2.UpdateAgentGroupResponse) error {
+func UpdateAgentGroup(req *proto.UpdateAgentGroupRequest, res *proto.UpdateAgentGroupResponse) error {
 	agentGroup := req.AgentGroup
 	if agentGroup == nil {
 		return common.ValidateErrorWithMsg("required field agentGroup could not be null")
@@ -46,7 +46,7 @@ func UpdateAgentGroup(req *protov2.UpdateAgentGroupRequest, res *protov2.UpdateA
 	return common.SystemError(err)
 }
 
-func DeleteAgentGroup(req *protov2.DeleteAgentGroupRequest, res *protov2.DeleteAgentGroupResponse) error {
+func DeleteAgentGroup(req *proto.DeleteAgentGroupRequest, res *proto.DeleteAgentGroupResponse) error {
 	agentGroupName := req.GroupName
 	if agentGroupName == "" {
 		return common.ValidateErrorWithMsg("required field groupName could not be null")
@@ -58,7 +58,7 @@ func DeleteAgentGroup(req *protov2.DeleteAgentGroupRequest, res *protov2.DeleteA
 	return common.SystemError(err)
 }
 
-func GetAgentGroup(req *protov2.GetAgentGroupRequest, res *protov2.GetAgentGroupResponse) error {
+func GetAgentGroup(req *proto.GetAgentGroupRequest, res *proto.GetAgentGroupResponse) error {
 	agentGroupName := req.GroupName
 	if agentGroupName == "" {
 		return common.ValidateErrorWithMsg("required field groupName could not be null")
@@ -72,12 +72,12 @@ func GetAgentGroup(req *protov2.GetAgentGroupRequest, res *protov2.GetAgentGroup
 	return nil
 }
 
-func ListAgentGroups(req *protov2.ListAgentGroupsRequest, res *protov2.ListAgentGroupsResponse) error {
+func ListAgentGroups(req *proto.ListAgentGroupsRequest, res *proto.ListAgentGroupsResponse) error {
 	agentGroups, err := repository.GetAllAgentGroup()
 	if err != nil {
 		return common.SystemError(err)
 	}
-	protoAgentGroups := make([]*protov2.AgentGroupTag, 0)
+	protoAgentGroups := make([]*proto.AgentGroupTag, 0)
 	for _, agentGroup := range agentGroups {
 		protoAgentGroups = append(protoAgentGroups, agentGroup.Parse2ProtoAgentGroupTag())
 	}
@@ -85,7 +85,7 @@ func ListAgentGroups(req *protov2.ListAgentGroupsRequest, res *protov2.ListAgent
 	return nil
 }
 
-func GetAppliedAgentGroupsForPipelineConfigName(req *protov2.GetAppliedAgentGroupsRequest, res *protov2.GetAppliedAgentGroupsResponse) error {
+func GetAppliedAgentGroupsForPipelineConfigName(req *proto.GetAppliedAgentGroupsRequest, res *proto.GetAppliedAgentGroupsResponse) error {
 	configName := req.ConfigName
 	if configName == "" {
 		return common.ValidateErrorWithMsg("required fields configName could not be null")
@@ -99,7 +99,7 @@ func GetAppliedAgentGroupsForPipelineConfigName(req *protov2.GetAppliedAgentGrou
 	return nil
 }
 
-func GetAppliedAgentGroupsForInstanceConfigName(req *protov2.GetAppliedAgentGroupsRequest, res *protov2.GetAppliedAgentGroupsResponse) error {
+func GetAppliedAgentGroupsForInstanceConfigName(req *proto.GetAppliedAgentGroupsRequest, res *proto.GetAppliedAgentGroupsResponse) error {
 	configName := req.ConfigName
 	if configName == "" {
 		return common.ValidateErrorWithMsg("required fields configName could not be null")
diff --git a/config_server/service/internal/service/instance_config.go b/config_server/service/service/instance_config.go
similarity index 96%
rename from config_server/service/internal/service/instance_config.go
rename to config_server/service/service/instance_config.go
index 9fa10a5419..71e4c18d95 100644
--- a/config_server/service/internal/service/instance_config.go
+++ b/config_server/service/service/instance_config.go
@@ -1,11 +1,11 @@
 package service
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/entity"
-	proto "config-server/internal/protov2"
-	"config-server/internal/repository"
-	"config-server/internal/utils"
+	"config-server/common"
+	"config-server/entity"
+	proto "config-server/protov2"
+	"config-server/repository"
+	"config-server/utils"
 )
 
 func CreateInstanceConfig(req *proto.CreateConfigRequest, res *proto.CreateConfigResponse) error {
diff --git a/config_server/service/internal/service/pipeline_config.go b/config_server/service/service/pipeline_config.go
similarity index 96%
rename from config_server/service/internal/service/pipeline_config.go
rename to config_server/service/service/pipeline_config.go
index dca5b8a686..3e7a8e2d72 100644
--- a/config_server/service/internal/service/pipeline_config.go
+++ b/config_server/service/service/pipeline_config.go
@@ -1,11 +1,11 @@
 package service
 
 import (
-	"config-server/internal/common"
-	"config-server/internal/entity"
-	proto "config-server/internal/protov2"
-	"config-server/internal/repository"
-	"config-server/internal/utils"
+	"config-server/common"
+	"config-server/entity"
+	proto "config-server/protov2"
+	"config-server/repository"
+	"config-server/utils"
 )
 
 func CreatePipelineConfig(req *proto.CreateConfigRequest, res *proto.CreateConfigResponse) error {
diff --git a/config_server/service/internal/store/gorm.go b/config_server/service/store/gorm.go
similarity index 98%
rename from config_server/service/internal/store/gorm.go
rename to config_server/service/store/gorm.go
index 1609d69db5..ec8b2555e1 100644
--- a/config_server/service/internal/store/gorm.go
+++ b/config_server/service/store/gorm.go
@@ -1,8 +1,8 @@
 package store
 
 import (
-	"config-server/internal/config"
-	"config-server/internal/entity"
+	"config-server/config"
+	"config-server/entity"
 	"fmt"
 	"gorm.io/gorm"
 	"log"
diff --git a/config_server/service/internal/store/gorm_test.go b/config_server/service/store/gorm_test.go
similarity index 100%
rename from config_server/service/internal/store/gorm_test.go
rename to config_server/service/store/gorm_test.go
diff --git a/config_server/service/internal/store/store.go b/config_server/service/store/store.go
similarity index 100%
rename from config_server/service/internal/store/store.go
rename to config_server/service/store/store.go
diff --git a/config_server/service/internal/utils/environment.go b/config_server/service/utils/environment.go
similarity index 100%
rename from config_server/service/internal/utils/environment.go
rename to config_server/service/utils/environment.go
diff --git a/config_server/service/internal/utils/json.go b/config_server/service/utils/json.go
similarity index 100%
rename from config_server/service/internal/utils/json.go
rename to config_server/service/utils/json.go
diff --git a/config_server/service/internal/utils/list.go b/config_server/service/utils/list.go
similarity index 100%
rename from config_server/service/internal/utils/list.go
rename to config_server/service/utils/list.go
diff --git a/config_server/service/internal/utils/str.go b/config_server/service/utils/str.go
similarity index 100%
rename from config_server/service/internal/utils/str.go
rename to config_server/service/utils/str.go
diff --git a/config_server/service/internal/utils/task.go b/config_server/service/utils/task.go
similarity index 100%
rename from config_server/service/internal/utils/task.go
rename to config_server/service/utils/task.go

From 946d27d5a2181fc484366b60df25e77e9d4e8234 Mon Sep 17 00:00:00 2001
From: Ww67652 <1749113286@qq.com>
Date: Mon, 30 Sep 2024 23:12:27 +0800
Subject: [PATCH 03/11] update: change directory structure

---
 config_server/service/cmd/main.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/config_server/service/cmd/main.go b/config_server/service/cmd/main.go
index 7a82ea6893..0c68566c45 100644
--- a/config_server/service/cmd/main.go
+++ b/config_server/service/cmd/main.go
@@ -1,8 +1,8 @@
 package main
 
 import (
-	"config-server/internal/config"
-	"config-server/internal/router"
+	"config-server/config"
+	"config-server/router"
 	"github.com/gin-gonic/gin"
 )
 

From ada083d5e5f36617356ca6e2d54f413fa0084eca Mon Sep 17 00:00:00 2001
From: Ww67652 <1749113286@qq.com>
Date: Mon, 21 Oct 2024 13:42:25 +0800
Subject: [PATCH 04/11] update: Modify the request method for heartbeat
 detection

---
 config_server/service/Dockerfile              |    1 +
 config_server/service/entity/agent.go         |   23 +-
 config_server/service/entity/base.go          |   12 +-
 config_server/service/entity/command.go       |    2 +
 .../service/entity/instance_config.go         |   96 ++
 .../service/entity/pipeline_config.go         |   96 ++
 config_server/service/handler/agent.go        |  153 +-
 config_server/service/handler/agent_group.go  |  184 +--
 config_server/service/handler/common.go       |   62 +
 .../service/handler/instance_config.go        |  205 +--
 .../service/handler/pipeline_config.go        |  207 +--
 config_server/service/manager/agent_group.go  |   77 +-
 .../service/manager/instance_config.go        |   56 +
 .../service/manager/pipeline_config.go        |   58 +
 config_server/service/manager/state/agent.go  |   98 ++
 config_server/service/manager/state/common.go |    6 +
 .../service/manager/state/request.go          |   63 +
 .../service/manager/state/response.go         |  142 ++
 config_server/service/manager/state/server.go |  118 ++
 config_server/service/protov2/README.md       |   39 +
 config_server/service/protov2/agent.pb.go     |  248 +---
 config_server/service/protov2/user.pb.go      | 1308 ++++++-----------
 config_server/service/repository/agent.go     |   37 +-
 .../service/repository/instance_config.go     |   63 +-
 .../service/repository/pipeline_config.go     |   61 +-
 config_server/service/router/router.go        |    6 +-
 config_server/service/service/agent.go        |   93 +-
 config_server/service/service/agent_group.go  |   15 +-
 .../service/service/instance_config.go        |   26 +-
 .../service/service/pipeline_config.go        |   30 +-
 config_server/service/store/gorm.go           |    4 -
 config_server/service/test/common_test.go     |   20 +
 config_server/service/utils/environment.go    |   22 +-
 config_server/service/utils/list.go           |   22 +-
 34 files changed, 1490 insertions(+), 2163 deletions(-)
 create mode 100644 config_server/service/entity/instance_config.go
 create mode 100644 config_server/service/entity/pipeline_config.go
 create mode 100644 config_server/service/handler/common.go
 create mode 100644 config_server/service/manager/instance_config.go
 create mode 100644 config_server/service/manager/pipeline_config.go
 create mode 100644 config_server/service/manager/state/agent.go
 create mode 100644 config_server/service/manager/state/common.go
 create mode 100644 config_server/service/manager/state/request.go
 create mode 100644 config_server/service/manager/state/response.go
 create mode 100644 config_server/service/manager/state/server.go
 create mode 100644 config_server/service/protov2/README.md
 create mode 100644 config_server/service/test/common_test.go

diff --git a/config_server/service/Dockerfile b/config_server/service/Dockerfile
index e2b10fcfe1..d80159bef2 100644
--- a/config_server/service/Dockerfile
+++ b/config_server/service/Dockerfile
@@ -18,6 +18,7 @@ WORKDIR /backend
 COPY --from=build /backend/cmd /backend/cmd
 COPY --from=build /backend/ConfigServer /backend/ConfigServer
 ENV GIN_MODE=release
+ENV GO_ENV=prod
 
 CMD sh -c "./ConfigServer"
 
diff --git a/config_server/service/entity/agent.go b/config_server/service/entity/agent.go
index 1146034192..5707bb5b98 100644
--- a/config_server/service/entity/agent.go
+++ b/config_server/service/entity/agent.go
@@ -56,16 +56,16 @@ func (a *AgentAttributes) Value() (driver.Value, error) {
 // Preload should write the name of the structure associated field, not the name of the data table or the name of the associated model structure
 
 type Agent struct {
-	SequenceNum     uint64
-	Capabilities    uint64
-	InstanceId      string `gorm:"primarykey"`
-	AgentType       string
-	Attributes      *AgentAttributes
-	Tags            []*AgentGroup `gorm:"many2many:agent_and_agent_group;foreignKey:InstanceId;joinForeignKey:AgentInstanceId;References:Name;joinReferences:AgentGroupName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
-	RunningStatus   string
-	StartupTime     int64
-	PipelineConfigs []*PipelineConfig `gorm:"many2many:agent_pipeline_config;foreignKey:InstanceId;joinForeignKey:AgentInstanceId;References:Name;joinReferences:PipelineConfigName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
-	InstanceConfigs []*InstanceConfig `gorm:"many2many:agent_instance_config;foreignKey:InstanceId;joinForeignKey:AgentInstanceId;References:Name;joinReferences:InstanceConfigName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+	SequenceNum            uint64
+	Capabilities           uint64
+	InstanceId             string `gorm:"primarykey"`
+	AgentType              string
+	Attributes             *AgentAttributes
+	Tags                   []*AgentGroup `gorm:"many2many:agent_and_agent_group;foreignKey:InstanceId;joinForeignKey:AgentInstanceId;References:Name;joinReferences:AgentGroupName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+	RunningStatus          string
+	StartupTime            int64
+	PipelineConfigStatuses PipelineConfigStatusList
+	InstanceConfigStatuses InstanceConfigStatusList
 	//CustomCommands  []*CommandInfo
 	Flags             uint64
 	Opaque            []byte
@@ -80,6 +80,8 @@ func (a Agent) Parse2Proto() *proto.Agent {
 	protoAgent.Attributes = a.Attributes.Parse2Proto()
 	protoAgent.RunningStatus = a.RunningStatus
 	protoAgent.StartupTime = a.StartupTime
+	protoAgent.PipelineConfigs = a.PipelineConfigStatuses.Parse2ProtoConfigStatus()
+	protoAgent.InstanceConfigs = a.InstanceConfigStatuses.Parse2ProtoConfigStatus()
 	return protoAgent
 }
 
@@ -99,7 +101,6 @@ func ParseHeartBeatRequest2BasicAgent(req *proto.HeartbeatRequest, lastHeartBeat
 
 	agent.RunningStatus = req.RunningStatus
 	agent.StartupTime = req.StartupTime
-
 	agent.Flags = req.Flags
 	agent.Opaque = req.Opaque
 	agent.LastHeartBeatTime = lastHeartBeatTime
diff --git a/config_server/service/entity/base.go b/config_server/service/entity/base.go
index a11e0983a6..5427e4e842 100644
--- a/config_server/service/entity/base.go
+++ b/config_server/service/entity/base.go
@@ -1,13 +1,11 @@
 package entity
 
 const (
-	agentTable               = "agent"
-	agentGroupTable          = "agent_group"
-	pipelineConfigTable      = "pipeline_config"
-	instanceConfigTable      = "instance_config"
-	commandInfoTable         = "command_info"
-	agentPipelineConfigTable = "agent_pipeline_config"
-	agentInstanceConfigTable = "agent_instance_config"
+	agentTable          = "agent"
+	agentGroupTable     = "agent_group"
+	pipelineConfigTable = "pipeline_config"
+	instanceConfigTable = "instance_config"
+	commandInfoTable    = "command_info"
 	//agentAndCommandTable     = "agent_command"
 )
 
diff --git a/config_server/service/entity/command.go b/config_server/service/entity/command.go
index 8768f39aec..40f83537f2 100644
--- a/config_server/service/entity/command.go
+++ b/config_server/service/entity/command.go
@@ -1,5 +1,7 @@
 package entity
 
+type ConfigStatus int32
+
 type CommandInfo struct {
 	Type       string
 	Name       string       `gorm:"primarykey"`
diff --git a/config_server/service/entity/instance_config.go b/config_server/service/entity/instance_config.go
new file mode 100644
index 0000000000..85d1ca0118
--- /dev/null
+++ b/config_server/service/entity/instance_config.go
@@ -0,0 +1,96 @@
+package entity
+
+import (
+	proto "config-server/protov2"
+	"database/sql/driver"
+	"encoding/json"
+	"errors"
+)
+
+type InstanceConfig struct {
+	Name        string `gorm:"primarykey"`
+	Version     int64
+	Detail      []byte
+	AgentGroups []*AgentGroup `gorm:"many2many:agent_group_instance_config;foreignKey:Name;joinForeignKey:InstanceConfigName;References:Name;joinReferences:AgentGroupName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+}
+
+func (InstanceConfig) TableName() string {
+	return instanceConfigTable
+}
+
+func (c InstanceConfig) Parse2ProtoInstanceConfigDetail(isContainDetail bool) *proto.ConfigDetail {
+	if isContainDetail {
+		return &proto.ConfigDetail{
+			Name:    c.Name,
+			Version: c.Version,
+			Detail:  c.Detail,
+		}
+	}
+	return &proto.ConfigDetail{
+		Name:    c.Name,
+		Version: c.Version,
+	}
+}
+
+func ParseProtoInstanceConfig2InstanceConfig(c *proto.ConfigDetail) *InstanceConfig {
+	return &InstanceConfig{
+		Name:    c.Name,
+		Version: c.Version,
+		Detail:  c.Detail,
+	}
+}
+
+type InstanceConfigStatus struct {
+	Name    string
+	Version int64
+	Status  ConfigStatus
+	Message string
+}
+
+func ParseProtoInstanceConfigStatus2InstanceConfigStatus(c *proto.ConfigInfo) *InstanceConfigStatus {
+	return &InstanceConfigStatus{
+		Name:    c.Name,
+		Version: c.Version,
+		Status:  ConfigStatus(c.Status),
+		Message: c.Message,
+	}
+}
+
+func (i InstanceConfigStatus) Parse2ProtoConfigInfo() *proto.ConfigInfo {
+	return &proto.ConfigInfo{
+		Name:    i.Name,
+		Version: i.Version,
+		Status:  proto.ConfigStatus(i.Status),
+		Message: i.Message,
+	}
+}
+
+type InstanceConfigStatusList []*InstanceConfigStatus
+
+func (i InstanceConfigStatusList) Parse2ProtoConfigStatus() []*proto.ConfigInfo {
+	protoConfigInfos := make([]*proto.ConfigInfo, 0)
+	for _, status := range i {
+		protoConfigInfos = append(protoConfigInfos, status.Parse2ProtoConfigInfo())
+	}
+	return protoConfigInfos
+}
+
+func ParseInstanceConfigStatusList2Proto(configInfos []*proto.ConfigInfo) InstanceConfigStatusList {
+	res := make(InstanceConfigStatusList, 0)
+	for _, configInfo := range configInfos {
+		res = append(res, ParseProtoInstanceConfigStatus2InstanceConfigStatus(configInfo))
+	}
+	return res
+}
+
+func (i InstanceConfigStatusList) Value() (driver.Value, error) {
+	return json.Marshal(i)
+}
+
+func (i *InstanceConfigStatusList) Scan(value any) error {
+	bytes, ok := value.([]byte)
+	if !ok {
+		return errors.New("type assertion to []byte failed")
+	}
+	return json.Unmarshal(bytes, i)
+}
diff --git a/config_server/service/entity/pipeline_config.go b/config_server/service/entity/pipeline_config.go
new file mode 100644
index 0000000000..e1cd36cd9d
--- /dev/null
+++ b/config_server/service/entity/pipeline_config.go
@@ -0,0 +1,96 @@
+package entity
+
+import (
+	proto "config-server/protov2"
+	"database/sql/driver"
+	"encoding/json"
+	"errors"
+)
+
+type PipelineConfig struct {
+	Name        string `gorm:"primarykey"`
+	Version     int64
+	Detail      []byte
+	AgentGroups []*AgentGroup `gorm:"many2many:agent_group_pipeline_config;foreignKey:Name;joinForeignKey:PipelineConfigName;References:Name;joinReferences:AgentGroupName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
+}
+
+func (PipelineConfig) TableName() string {
+	return pipelineConfigTable
+}
+
+func (c PipelineConfig) Parse2ProtoPipelineConfigDetail(isContainDetail bool) *proto.ConfigDetail {
+	if isContainDetail {
+		return &proto.ConfigDetail{
+			Name:    c.Name,
+			Version: c.Version,
+			Detail:  c.Detail,
+		}
+	}
+	return &proto.ConfigDetail{
+		Name:    c.Name,
+		Version: c.Version,
+	}
+}
+
+func ParseProtoPipelineConfig2PipelineConfig(c *proto.ConfigDetail) *PipelineConfig {
+	return &PipelineConfig{
+		Name:    c.Name,
+		Version: c.Version,
+		Detail:  c.Detail,
+	}
+}
+
+type PipelineConfigStatus struct {
+	Name    string
+	Version int64
+	Status  ConfigStatus
+	Message string
+}
+
+func ParseProtoPipelineConfigStatus2PipelineConfigStatus(c *proto.ConfigInfo) *PipelineConfigStatus {
+	return &PipelineConfigStatus{
+		Name:    c.Name,
+		Version: c.Version,
+		Status:  ConfigStatus(c.Status),
+		Message: c.Message,
+	}
+}
+
+func (p PipelineConfigStatus) Parse2ProtoConfigInfo() *proto.ConfigInfo {
+	return &proto.ConfigInfo{
+		Name:    p.Name,
+		Version: p.Version,
+		Status:  proto.ConfigStatus(p.Status),
+		Message: p.Message,
+	}
+}
+
+type PipelineConfigStatusList []*PipelineConfigStatus
+
+func (p PipelineConfigStatusList) Parse2ProtoConfigStatus() []*proto.ConfigInfo {
+	protoConfigInfos := make([]*proto.ConfigInfo, 0)
+	for _, status := range p {
+		protoConfigInfos = append(protoConfigInfos, status.Parse2ProtoConfigInfo())
+	}
+	return protoConfigInfos
+}
+
+func ParsePipelineConfigStatusList2Proto(configInfos []*proto.ConfigInfo) PipelineConfigStatusList {
+	res := make(PipelineConfigStatusList, 0)
+	for _, configInfo := range configInfos {
+		res = append(res, ParseProtoPipelineConfigStatus2PipelineConfigStatus(configInfo))
+	}
+	return res
+}
+
+func (p PipelineConfigStatusList) Value() (driver.Value, error) {
+	return json.Marshal(p)
+}
+
+func (p *PipelineConfigStatusList) Scan(value any) error {
+	bytes, ok := value.([]byte)
+	if !ok {
+		return errors.New("type assertion to []byte failed")
+	}
+	return json.Unmarshal(bytes, p)
+}
diff --git a/config_server/service/handler/agent.go b/config_server/service/handler/agent.go
index d4defadf85..bd769c9da8 100644
--- a/config_server/service/handler/agent.go
+++ b/config_server/service/handler/agent.go
@@ -1,158 +1,17 @@
 package handler
 
 import (
-	"config-server/common"
 	"config-server/config"
-	"config-server/protov2"
 	"config-server/service"
-	"github.com/gin-gonic/gin"
-	"github.com/gin-gonic/gin/binding"
 )
 
 func CheckAgentExist() {
 	go service.CheckAgentExist(config.ServerConfigInstance.TimeLimit)
 }
 
-func HeartBeat(c *gin.Context) {
-	request := &protov2.HeartbeatRequest{}
-	response := &protov2.HeartbeatResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.HeartBeat(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func FetchPipelineConfig(c *gin.Context) {
-	request := &protov2.FetchConfigRequest{}
-	response := &protov2.FetchConfigResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.FetchPipelineConfigDetail(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func FetchInstanceConfig(c *gin.Context) {
-	request := &protov2.FetchConfigRequest{}
-	response := &protov2.FetchConfigResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.FetchInstanceConfigDetail(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func ListAgentsInGroup(c *gin.Context) {
-	request := &protov2.ListAgentsRequest{}
-	response := &protov2.ListAgentsResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.ListAgentsInGroup(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func GetPipelineConfigStatusList(c *gin.Context) {
-	request := &protov2.GetConfigStatusListRequest{}
-	response := &protov2.GetConfigStatusListResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.GetPipelineConfigStatusList(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func GetInstanceConfigStatusList(c *gin.Context) {
-	request := &protov2.GetConfigStatusListRequest{}
-	response := &protov2.GetConfigStatusListResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.GetInstanceConfigStatusList(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
+var (
+	HeartBeat           = ProtobufHandler(service.HeartBeat)
+	FetchPipelineConfig = ProtobufHandler(service.FetchPipelineConfigDetail)
+	FetchInstanceConfig = ProtobufHandler(service.FetchInstanceConfigDetail)
+	ListAgentsInGroup   = ProtobufHandler(service.ListAgentsInGroup)
+)
diff --git a/config_server/service/handler/agent_group.go b/config_server/service/handler/agent_group.go
index 06e32f8565..15637b7640 100644
--- a/config_server/service/handler/agent_group.go
+++ b/config_server/service/handler/agent_group.go
@@ -1,181 +1,15 @@
 package handler
 
 import (
-	"config-server/common"
-	proto "config-server/protov2"
 	"config-server/service"
-	"github.com/gin-gonic/gin"
-	"github.com/gin-gonic/gin/binding"
 )
 
-func AppliedOrRemoveConfigForAgentGroup() {
-	go service.AppliedOrRemoveConfigForAgentGroup(30)
-}
-
-func CreateAgentGroup(c *gin.Context) {
-	request := &proto.CreateAgentGroupRequest{}
-	response := &proto.CreateAgentGroupResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.CreateAgentGroup(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func UpdateAgentGroup(c *gin.Context) {
-	request := &proto.UpdateAgentGroupRequest{}
-	response := &proto.UpdateAgentGroupResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.UpdateAgentGroup(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func DeleteAgentGroup(c *gin.Context) {
-	request := &proto.DeleteAgentGroupRequest{}
-	response := &proto.DeleteAgentGroupResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.DeleteAgentGroup(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func GetAgentGroup(c *gin.Context) {
-	request := &proto.GetAgentGroupRequest{}
-	response := &proto.GetAgentGroupResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.GetAgentGroup(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func ListAgentGroups(c *gin.Context) {
-	request := &proto.ListAgentGroupsRequest{}
-	response := &proto.ListAgentGroupsResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.ListAgentGroups(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func GetAppliedPipelineConfigsForAgentGroup(c *gin.Context) {
-	request := &proto.GetAppliedConfigsForAgentGroupRequest{}
-	response := &proto.GetAppliedConfigsForAgentGroupResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.GetAppliedPipelineConfigsForAgentGroup(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func GetAppliedInstanceConfigsForAgentGroup(c *gin.Context) {
-	request := &proto.GetAppliedConfigsForAgentGroupRequest{}
-	response := &proto.GetAppliedConfigsForAgentGroupResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.GetAppliedInstanceConfigsForAgentGroup(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
+var (
+	CreateAgentGroup                       = ProtobufHandler(service.CreateAgentGroup)
+	UpdateAgentGroup                       = ProtobufHandler(service.UpdateAgentGroup)
+	DeleteAgentGroup                       = ProtobufHandler(service.DeleteAgentGroup)
+	GetAgentGroup                          = ProtobufHandler(service.GetAgentGroup)
+	ListAgentGroups                        = ProtobufHandler(service.ListAgentGroups)
+	GetAppliedPipelineConfigsForAgentGroup = ProtobufHandler(service.GetAppliedPipelineConfigsForAgentGroup)
+	GetAppliedInstanceConfigsForAgentGroup = ProtobufHandler(service.GetAppliedInstanceConfigsForAgentGroup)
+)
diff --git a/config_server/service/handler/common.go b/config_server/service/handler/common.go
new file mode 100644
index 0000000000..c19ccce468
--- /dev/null
+++ b/config_server/service/handler/common.go
@@ -0,0 +1,62 @@
+package handler
+
+import (
+	"config-server/common"
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+	"log"
+	"reflect"
+	"strings"
+)
+
+type ProtobufFunc[T any, R any] func(request *T, response *R) error
+
+func ProtobufHandler[T any, R any](handler ProtobufFunc[T, R]) gin.HandlerFunc {
+	return func(c *gin.Context) {
+		var err error
+		request := new(T)
+		response := new(R)
+
+		defer func() {
+			responseCommon := common.GenerateCommonResponse(err)
+			reflect.ValueOf(response).Elem().FieldByName("CommonResponse").Set(reflect.ValueOf(responseCommon))
+			common.SuccessProtobufRes(c, response)
+		}()
+		err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
+
+		requestId := reflect.ValueOf(request).Elem().FieldByName("RequestId").Bytes()
+		reflect.ValueOf(response).Elem().FieldByName("RequestId").Set(reflect.ValueOf(requestId))
+		if requestId == nil {
+			err = common.ValidateErrorWithMsg("required fields requestId could not be null")
+			return
+		}
+
+		if err != nil {
+			err = common.SystemError(err)
+			return
+		}
+
+		//err = (RequestLogger(c.Request.URL.String(), handler))(request, response)
+		err = (handler)(request, response)
+		if err != nil {
+			err = common.SystemError(err)
+			return
+		}
+	}
+}
+
+func RequestLogger[T any, R any](url string, handler ProtobufFunc[T, R]) ProtobufFunc[T, R] {
+	return func(req *T, res *R) error {
+		if strings.Contains(url, "Heart") {
+			log.Printf("%s REQUEST:%+v", url, req)
+		}
+		err := handler(req, res)
+		if err != nil {
+			return common.SystemError(err)
+		}
+		if strings.Contains(url, "Heart") {
+			log.Printf("%s RESPONSE:%+v", url, res)
+		}
+		return nil
+	}
+}
diff --git a/config_server/service/handler/instance_config.go b/config_server/service/handler/instance_config.go
index 1be64a667d..73009dfa6f 100644
--- a/config_server/service/handler/instance_config.go
+++ b/config_server/service/handler/instance_config.go
@@ -1,201 +1,16 @@
 package handler
 
 import (
-	"config-server/common"
-	proto "config-server/protov2"
 	"config-server/service"
-	"github.com/gin-gonic/gin"
-	"github.com/gin-gonic/gin/binding"
 )
 
-func CreateInstanceConfig(c *gin.Context) {
-	request := &proto.CreateConfigRequest{}
-	response := &proto.CreateConfigResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.CreateInstanceConfig(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func UpdateInstanceConfig(c *gin.Context) {
-	request := &proto.UpdateConfigRequest{}
-	response := &proto.UpdateConfigResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.UpdateInstanceConfig(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func DeleteInstanceConfig(c *gin.Context) {
-	request := &proto.DeleteConfigRequest{}
-	response := &proto.DeleteConfigResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.DeleteInstanceConfig(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func GetInstanceConfig(c *gin.Context) {
-	request := &proto.GetConfigRequest{}
-	response := &proto.GetConfigResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.GetInstanceConfig(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func ListInstanceConfigs(c *gin.Context) {
-	request := &proto.ListConfigsRequest{}
-	response := &proto.ListConfigsResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.ListInstanceConfigs(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func ApplyInstanceConfigToAgentGroup(c *gin.Context) {
-	request := &proto.ApplyConfigToAgentGroupRequest{}
-	response := &proto.ApplyConfigToAgentGroupResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.ApplyInstanceConfigToAgentGroup(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func RemoveInstanceConfigFromAgentGroup(c *gin.Context) {
-	request := &proto.RemoveConfigFromAgentGroupRequest{}
-	response := &proto.RemoveConfigFromAgentGroupResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.RemoveInstanceConfigFromAgentGroup(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func GetAppliedAgentGroupsWithInstanceConfig(c *gin.Context) {
-	request := &proto.GetAppliedAgentGroupsRequest{}
-	response := &proto.GetAppliedAgentGroupsResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.GetAppliedAgentGroupsForInstanceConfigName(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
+var (
+	CreateInstanceConfig                    = ProtobufHandler(service.CreateInstanceConfig)
+	UpdateInstanceConfig                    = ProtobufHandler(service.UpdateInstanceConfig)
+	DeleteInstanceConfig                    = ProtobufHandler(service.DeleteInstanceConfig)
+	GetInstanceConfig                       = ProtobufHandler(service.GetInstanceConfig)
+	ListInstanceConfigs                     = ProtobufHandler(service.ListInstanceConfigs)
+	ApplyInstanceConfigToAgentGroup         = ProtobufHandler(service.ApplyInstanceConfigToAgentGroup)
+	RemoveInstanceConfigFromAgentGroup      = ProtobufHandler(service.RemoveInstanceConfigFromAgentGroup)
+	GetAppliedAgentGroupsWithInstanceConfig = ProtobufHandler(service.GetAppliedAgentGroupsForInstanceConfigName)
+)
diff --git a/config_server/service/handler/pipeline_config.go b/config_server/service/handler/pipeline_config.go
index 752ced81cc..25d16cdf38 100644
--- a/config_server/service/handler/pipeline_config.go
+++ b/config_server/service/handler/pipeline_config.go
@@ -1,203 +1,16 @@
 package handler
 
 import (
-	"config-server/common"
-	proto "config-server/protov2"
 	"config-server/service"
-	"github.com/gin-gonic/gin"
-	"github.com/gin-gonic/gin/binding"
 )
 
-func CreatePipelineConfig(c *gin.Context) {
-	request := &proto.CreateConfigRequest{}
-	response := &proto.CreateConfigResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.CreatePipelineConfig(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func UpdatePipelineConfig(c *gin.Context) {
-	request := &proto.UpdateConfigRequest{}
-	response := &proto.UpdateConfigResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.UpdatePipelineConfig(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func DeletePipelineConfig(c *gin.Context) {
-	request := &proto.DeleteConfigRequest{}
-	response := &proto.DeleteConfigResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.DeletePipelineConfig(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func GetPipelineConfig(c *gin.Context) {
-	request := &proto.GetConfigRequest{}
-	response := &proto.GetConfigResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.GetPipelineConfig(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func ListPipelineConfigs(c *gin.Context) {
-	request := &proto.ListConfigsRequest{}
-	response := &proto.ListConfigsResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.ListPipelineConfigs(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-// 对于之前应用到组的配置,若后续有agent加入到组里面,是否需要更新
-
-func ApplyPipelineConfigToAgentGroup(c *gin.Context) {
-	request := &proto.ApplyConfigToAgentGroupRequest{}
-	response := &proto.ApplyConfigToAgentGroupResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.ApplyPipelineConfigToAgentGroup(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func RemovePipelineConfigFromAgentGroup(c *gin.Context) {
-	request := &proto.RemoveConfigFromAgentGroupRequest{}
-	response := &proto.RemoveConfigFromAgentGroupResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.RemovePipelineConfigFromAgentGroup(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
-
-func GetAppliedAgentGroupsWithPipelineConfig(c *gin.Context) {
-	request := &proto.GetAppliedAgentGroupsRequest{}
-	response := &proto.GetAppliedAgentGroupsResponse{}
-	var err error
-	defer func() {
-		response.CommonResponse = common.GenerateCommonResponse(err)
-		common.SuccessProtobufRes(c, response)
-	}()
-	err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
-	response.RequestId = request.RequestId
-	if response.RequestId == nil {
-		err = common.ValidateErrorWithMsg("required fields requestId could not be null")
-	}
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-	err = service.GetAppliedAgentGroupsForPipelineConfigName(request, response)
-	if err != nil {
-		err = common.SystemError(err)
-		return
-	}
-}
+var (
+	CreatePipelineConfig                    = ProtobufHandler(service.CreatePipelineConfig)
+	UpdatePipelineConfig                    = ProtobufHandler(service.UpdatePipelineConfig)
+	DeletePipelineConfig                    = ProtobufHandler(service.DeletePipelineConfig)
+	GetPipelineConfig                       = ProtobufHandler(service.GetPipelineConfig)
+	ListPipelineConfigs                     = ProtobufHandler(service.ListPipelineConfigs)
+	ApplyPipelineConfigToAgentGroup         = ProtobufHandler(service.ApplyPipelineConfigToAgentGroup)
+	RemovePipelineConfigFromAgentGroup      = ProtobufHandler(service.RemovePipelineConfigFromAgentGroup)
+	GetAppliedAgentGroupsWithPipelineConfig = ProtobufHandler(service.GetAppliedAgentGroupsForPipelineConfigName)
+)
diff --git a/config_server/service/manager/agent_group.go b/config_server/service/manager/agent_group.go
index 553d3e339b..a0393deae6 100644
--- a/config_server/service/manager/agent_group.go
+++ b/config_server/service/manager/agent_group.go
@@ -2,86 +2,15 @@ package manager
 
 import (
 	"config-server/entity"
-	"config-server/repository"
-	"config-server/utils"
+	proto "config-server/protov2"
 )
 
-func AddDefaultAgentGroup(agentTags []*entity.AgentGroup) []*entity.AgentGroup {
+func AddDefaultAgentGroup(agentTags []*proto.AgentGroupTag) []*proto.AgentGroupTag {
 	if agentTags == nil || len(agentTags) == 0 {
-		agentTags = append(agentTags, &entity.AgentGroup{
+		agentTags = append(agentTags, &proto.AgentGroupTag{
 			Name:  entity.AgentGroupDefaultValue,
 			Value: entity.AgentGroupDefaultValue,
 		})
 	}
 	return agentTags
 }
-
-func AppliedOrRemovePipelineConfigForAgentGroup(agentGroupDetails []*entity.AgentGroup) {
-	agentPipelineConfigList := repository.ListAgentPipelineConfig()
-	processAgentPipelineConfigMapList := make([]*entity.AgentPipelineConfig, 0)
-	for _, agentGroupDetail := range agentGroupDetails {
-		agents := agentGroupDetail.Agents
-
-		pipelineConfigs := agentGroupDetail.PipelineConfigs
-		for _, agent := range agents {
-			for _, pipelineConfig := range pipelineConfigs {
-				a := &entity.AgentPipelineConfig{
-					AgentInstanceId:    agent.InstanceId,
-					PipelineConfigName: pipelineConfig.Name,
-				}
-				//以agentGroup中 group与agent的关系为主
-				if !utils.ContainElement(processAgentPipelineConfigMapList, a, (*entity.AgentPipelineConfig).Equals) {
-					processAgentPipelineConfigMapList = append(processAgentPipelineConfigMapList, a)
-				}
-			}
-		}
-		// 如果agent与config的关系 存在于 agentGroup与config的关系中,则以前者为主
-		for _, agentPipelineConfig := range agentPipelineConfigList {
-			utils.ReplaceElement(processAgentPipelineConfigMapList, agentPipelineConfig, (*entity.AgentPipelineConfig).Equals)
-		}
-
-	}
-	repository.DeleteAllPipelineConfigAndAgent()
-	if processAgentPipelineConfigMapList != nil && len(processAgentPipelineConfigMapList) != 0 {
-		err := CreateOrUpdateAgentPipelineConfigs(processAgentPipelineConfigMapList)
-		if err != nil {
-			panic(err)
-		}
-	}
-}
-
-func AppliedOrRemoveInstanceConfigForAgentGroup(agentGroupDetails []*entity.AgentGroup) {
-	agentInstanceConfigList := repository.ListAgentInstanceConfig()
-	processAgentInstanceConfigMapList := make([]*entity.AgentInstanceConfig, 0)
-	for _, agentGroupDetail := range agentGroupDetails {
-		agents := agentGroupDetail.Agents
-
-		instanceConfigs := agentGroupDetail.InstanceConfigs
-		for _, agent := range agents {
-			for _, instanceConfig := range instanceConfigs {
-				a := &entity.AgentInstanceConfig{
-					AgentInstanceId:    agent.InstanceId,
-					InstanceConfigName: instanceConfig.Name,
-				}
-				//以agentGroup中 group与agent的关系为主
-				if !utils.ContainElement(processAgentInstanceConfigMapList, a, (*entity.AgentInstanceConfig).Equals) {
-					processAgentInstanceConfigMapList = append(processAgentInstanceConfigMapList, a)
-				}
-			}
-		}
-		// 如果agent与config的关系 存在于 agentGroup与config的关系中,则以前者为主
-		for _, agentInstanceConfig := range agentInstanceConfigList {
-			utils.ReplaceElement(processAgentInstanceConfigMapList, agentInstanceConfig, (*entity.AgentInstanceConfig).Equals)
-		}
-
-	}
-
-	repository.DeleteAllInstanceConfigAndAgent()
-	if processAgentInstanceConfigMapList != nil && len(processAgentInstanceConfigMapList) != 0 {
-		err := CreateOrUpdateAgentInstanceConfigs(processAgentInstanceConfigMapList)
-		if err != nil {
-			panic(err)
-		}
-	}
-
-}
diff --git a/config_server/service/manager/instance_config.go b/config_server/service/manager/instance_config.go
new file mode 100644
index 0000000000..0c3bd68e45
--- /dev/null
+++ b/config_server/service/manager/instance_config.go
@@ -0,0 +1,56 @@
+package manager
+
+import (
+	"config-server/common"
+	"config-server/entity"
+	proto "config-server/protov2"
+	"config-server/repository"
+	"config-server/utils"
+)
+
+func SaveInstanceConfigStatus(configs []*proto.ConfigInfo, instanceId string) error {
+	if configs == nil {
+		return nil
+	}
+	agent := &entity.Agent{
+		InstanceId: instanceId,
+	}
+	for _, instanceConfig := range configs {
+		agent.InstanceConfigStatuses =
+			append(agent.InstanceConfigStatuses, entity.ParseProtoInstanceConfigStatus2InstanceConfigStatus(instanceConfig))
+	}
+
+	err := repository.UpdateAgentById(agent, "instance_config_statuses")
+	return common.SystemError(err)
+}
+
+func GetInstanceConfigs(instanceId string, configInfos []*proto.ConfigInfo, isContainDetail bool) ([]*proto.ConfigDetail, error) {
+	var err error
+	agent := &entity.Agent{InstanceId: instanceId}
+	err = repository.GetInstanceConfigsByAgent(agent)
+	if err != nil {
+		return nil, err
+	}
+
+	configUpdates := make([]*entity.InstanceConfig, 0)
+	configEqFunc := func(a *entity.InstanceConfig, b *entity.InstanceConfig) bool {
+		return a.Name == b.Name
+	}
+	configInfoEqFunc := func(a *proto.ConfigInfo, b *entity.InstanceConfig) bool {
+		return a.Name == b.Name && a.Version == b.Version
+	}
+
+	for _, tag := range agent.Tags {
+		for _, config := range tag.InstanceConfigs {
+			//存在某些组里有重复配置的情况,需进行剔除;配置没更新(即版本没变化的)也无需加入数组
+			if !utils.ContainElement(configInfos, config, configInfoEqFunc) &&
+				!utils.ContainElement(configUpdates, config, configEqFunc) {
+				configUpdates = append(configUpdates, config)
+			}
+		}
+	}
+
+	return utils.Map(configUpdates, func(config *entity.InstanceConfig) *proto.ConfigDetail {
+		return (*config).Parse2ProtoInstanceConfigDetail(isContainDetail)
+	}), nil
+}
diff --git a/config_server/service/manager/pipeline_config.go b/config_server/service/manager/pipeline_config.go
new file mode 100644
index 0000000000..cd0d703f9e
--- /dev/null
+++ b/config_server/service/manager/pipeline_config.go
@@ -0,0 +1,58 @@
+package manager
+
+import (
+	"config-server/common"
+	"config-server/entity"
+	proto "config-server/protov2"
+	"config-server/repository"
+	"config-server/utils"
+)
+
+func SavePipelineConfigStatus(configs []*proto.ConfigInfo, instanceId string) error {
+	if configs == nil {
+		return nil
+	}
+	agent := &entity.Agent{
+		InstanceId: instanceId,
+	}
+	for _, pipelineConfig := range configs {
+		agent.PipelineConfigStatuses =
+			append(agent.PipelineConfigStatuses, entity.ParseProtoPipelineConfigStatus2PipelineConfigStatus(pipelineConfig))
+	}
+
+	err := repository.UpdateAgentById(agent, "pipeline_config_statuses")
+	return common.SystemError(err)
+}
+
+//configNames:需要的config ;instanceId:用于查询agent在哪些group中,最终查询它拥有的config
+
+func GetPipelineConfigs(instanceId string, configInfos []*proto.ConfigInfo, isContainDetail bool) ([]*proto.ConfigDetail, error) {
+	var err error
+	agent := &entity.Agent{InstanceId: instanceId}
+	err = repository.GetPipelineConfigsByAgent(agent)
+	if err != nil {
+		return nil, err
+	}
+
+	configUpdates := make([]*entity.PipelineConfig, 0)
+	configEqFunc := func(a *entity.PipelineConfig, b *entity.PipelineConfig) bool {
+		return a.Name == b.Name
+	}
+	configInfoEqFunc := func(a *proto.ConfigInfo, b *entity.PipelineConfig) bool {
+		return a.Name == b.Name && a.Version == b.Version
+	}
+
+	for _, tag := range agent.Tags {
+		for _, config := range tag.PipelineConfigs {
+			//存在某些组里有重复配置的情况,需进行剔除;配置没更新(即版本没变化的)也无需加入数组
+			if !utils.ContainElement(configInfos, config, configInfoEqFunc) &&
+				!utils.ContainElement(configUpdates, config, configEqFunc) {
+				configUpdates = append(configUpdates, config)
+			}
+		}
+	}
+
+	return utils.Map(configUpdates, func(config *entity.PipelineConfig) *proto.ConfigDetail {
+		return (*config).Parse2ProtoPipelineConfigDetail(isContainDetail)
+	}), nil
+}
diff --git a/config_server/service/manager/state/agent.go b/config_server/service/manager/state/agent.go
new file mode 100644
index 0000000000..20b5e92525
--- /dev/null
+++ b/config_server/service/manager/state/agent.go
@@ -0,0 +1,98 @@
+package state
+
+import (
+	"config-server/common"
+	proto "config-server/protov2"
+	"log"
+)
+
+type AgentAction struct {
+	Base
+	Run func(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error
+}
+
+var (
+	AgentUnSpecified      = Base{Code: 0, Value: "unspecified"}
+	AcceptsPipelineConfig = Base{Code: 1, Value: "acceptsPipelineConfig"}
+	AcceptsInstanceConfig = Base{Code: 2, Value: "acceptsInstanceConfig"}
+	AcceptsCustomCommand  = Base{Code: 4, Value: "acceptsCustomCommand"}
+)
+
+var agentActionList = []*AgentAction{
+	{
+		Base: AgentUnSpecified,
+		Run:  UnspecifiedRun,
+	},
+	{
+		Base: AcceptsPipelineConfig,
+		Run:  AcceptsPipelineConfigRun,
+	},
+	{
+		Base: AcceptsInstanceConfig,
+		Run:  AcceptsInstanceConfigRun,
+	},
+	{
+		Base: AcceptsCustomCommand,
+		Run:  AcceptsCustomCommandRun,
+	},
+}
+
+//agent有接收某种配置的能力,则响应中设置对应的配置
+
+func UnspecifiedRun(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error {
+	return nil
+}
+
+// AcceptsPipelineConfigRun 返回PipelineConfigDetail
+func AcceptsPipelineConfigRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	// 心跳检测中返回config
+	err := UnspecifiedResponseAction.Run(req, res)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	//不在心跳检测中返回,需要额外请求
+	err = FetchPipelineConfigDetailResponseAction.Run(req, res)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	return nil
+}
+
+// AcceptsInstanceConfigRun 返回InstanceConfigDetail
+func AcceptsInstanceConfigRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	// 在心跳检测就返回config
+	err := UnspecifiedResponseAction.Run(req, res)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	err = FetchInstanceConfigDetailResponseAction.Run(req, res)
+	if err != nil {
+		return common.SystemError(err)
+	}
+	return nil
+}
+
+func AcceptsCustomCommandRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	log.Print("command capability action Run ...")
+	return nil
+}
+
+func HandleAgentCapabilities(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	err := HandleResponseFlags(res)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	for _, action := range agentActionList {
+		code := action.Code
+		if int(req.Capabilities)&code == code {
+			err := action.Run(req, res)
+			if err != nil {
+				return common.SystemError(err)
+			}
+		}
+	}
+	return nil
+}
diff --git a/config_server/service/manager/state/common.go b/config_server/service/manager/state/common.go
new file mode 100644
index 0000000000..073f4def24
--- /dev/null
+++ b/config_server/service/manager/state/common.go
@@ -0,0 +1,6 @@
+package state
+
+type Base struct {
+	Code  int
+	Value string
+}
diff --git a/config_server/service/manager/state/request.go b/config_server/service/manager/state/request.go
new file mode 100644
index 0000000000..9c71927eab
--- /dev/null
+++ b/config_server/service/manager/state/request.go
@@ -0,0 +1,63 @@
+package state
+
+import (
+	"config-server/common"
+	proto "config-server/protov2"
+)
+
+type RequestAction struct {
+	Base
+	Run func(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error
+}
+
+var (
+	RequestUnspecified     = Base{0, "unspecified"}
+	RequestReportFullState = Base{1, "reportFullState"}
+)
+
+var requestActionList = []*RequestAction{
+	{
+		Base: RequestUnspecified,
+		Run:  RequestUnspecifiedRun,
+	},
+	{
+		Base: RequestReportFullState,
+		Run:  RequestReportFullStateRun,
+	},
+}
+
+// RequestUnspecifiedRun agent上报简单信息
+func RequestUnspecifiedRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	//todo agent的flag一点用都没有啊,上传全量信息的时候也置为0
+	return RequestReportFullStateRun(req, res)
+	//return nil
+}
+
+// RequestReportFullStateRun agent上传全量信息
+func RequestReportFullStateRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	for _, action := range ServerActionList {
+		err := action.Action(req, res)
+		if err != nil {
+			return common.SystemError(err)
+		}
+	}
+	return nil
+}
+
+func HandleRequestFlags(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	err := HandleServerCapabilities(res)
+	if err != nil {
+		return common.SystemError(err)
+	}
+
+	for _, action := range requestActionList {
+		code := action.Code
+		if int(req.Flags)&code == code {
+			err := action.Run(req, res)
+			if err != nil {
+				return common.SystemError(err)
+			}
+		}
+	}
+	return nil
+}
diff --git a/config_server/service/manager/state/response.go b/config_server/service/manager/state/response.go
new file mode 100644
index 0000000000..118a4787a7
--- /dev/null
+++ b/config_server/service/manager/state/response.go
@@ -0,0 +1,142 @@
+package state
+
+import (
+	"config-server/common"
+	"config-server/config"
+	"config-server/manager"
+	proto "config-server/protov2"
+)
+
+type ResponseAction struct {
+	Base
+	Run func(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error
+}
+
+func (r ResponseAction) UpdateFlags(res *proto.HeartbeatResponse) error {
+	responseFlagType := r.Value
+	hasResponseFlag := config.ServerConfigInstance.ResponseFlags[responseFlagType]
+
+	if hasResponseFlag {
+		res.Flags = res.Flags | uint64(r.Code)
+	}
+	return nil
+}
+
+var (
+	Unspecified               = Base{0, "unspecified"}
+	ReportFullState           = Base{1, "reportFullState"}
+	FetchPipelineConfigDetail = Base{2, "fetchPipelineConfigDetail"}
+	FetchInstanceConfigDetail = Base{4, "fetchInstanceConfigDetail"}
+)
+
+var (
+	UnspecifiedResponseAction               = new(ResponseAction)
+	ReportFullStateResponseAction           = new(ResponseAction)
+	FetchPipelineConfigDetailResponseAction = new(ResponseAction)
+	FetchInstanceConfigDetailResponseAction = new(ResponseAction)
+)
+
+func init() {
+	UnspecifiedResponseAction.Base = Unspecified
+	UnspecifiedResponseAction.Run = ResponseUnspecifiedRun
+
+	ReportFullStateResponseAction.Base = ReportFullState
+	ReportFullStateResponseAction.Run = ResponseReportFullStateRun
+
+	FetchPipelineConfigDetailResponseAction.Base = FetchPipelineConfigDetail
+	FetchPipelineConfigDetailResponseAction.Run = FetchPipelineConfigDetailRun
+
+	FetchInstanceConfigDetailResponseAction.Base = FetchInstanceConfigDetail
+	FetchInstanceConfigDetailResponseAction.Run = FetchInstanceConfigDetailRun
+}
+
+var ResponseList = []*ResponseAction{
+	{
+		Base: Unspecified,
+		Run:  ResponseUnspecifiedRun,
+	},
+	{
+		Base: ReportFullState,
+		Run:  ResponseReportFullStateRun,
+	},
+	{
+		Base: FetchPipelineConfigDetail,
+		Run:  FetchPipelineConfigDetailRun,
+	},
+	{
+		Base: FetchInstanceConfigDetail,
+		Run:  FetchInstanceConfigDetailRun,
+	},
+}
+
+func ResponseUnspecifiedRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	fetchPipelineConfigKey := FetchPipelineConfigDetailResponseAction.Value
+	needFetchPipelineConfig := config.ServerConfigInstance.ResponseFlags[fetchPipelineConfigKey]
+	if !needFetchPipelineConfig {
+		strInstanceId := string(req.InstanceId)
+
+		pipelineConfigUpdates, err := manager.GetPipelineConfigs(strInstanceId, req.PipelineConfigs, true)
+		if err != nil {
+			return common.SystemError(err)
+		}
+		res.PipelineConfigUpdates = pipelineConfigUpdates
+	}
+
+	fetchInstanceConfigKey := FetchInstanceConfigDetailResponseAction.Value
+	needFetchInstanceConfig := config.ServerConfigInstance.ResponseFlags[fetchInstanceConfigKey]
+	if !needFetchInstanceConfig {
+		strInstanceId := string(req.InstanceId)
+
+		instanceConfigUpdates, err := manager.GetInstanceConfigs(strInstanceId, req.InstanceConfigs, true)
+		if err != nil {
+			return common.SystemError(err)
+		}
+		res.InstanceConfigUpdates = instanceConfigUpdates
+	}
+	return nil
+}
+
+func ResponseReportFullStateRun(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error {
+	return nil
+}
+
+// FetchPipelineConfigDetailRun 要求agent做的事情,比如配置不发送pipelineConfig的Detail,
+// 这里就要求它主动请求FetchPipelineConfig接口(只需改变res.flags并且configUpdate不包含detail)
+func FetchPipelineConfigDetailRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	key := FetchPipelineConfigDetailResponseAction.Value
+	needFetchConfig := config.ServerConfigInstance.ResponseFlags[key]
+	if needFetchConfig {
+		strInstanceId := string(req.InstanceId)
+		pipelineConfigUpdates, err := manager.GetPipelineConfigs(strInstanceId, req.PipelineConfigs, false)
+		if err != nil {
+			return common.SystemError(err)
+		}
+		res.PipelineConfigUpdates = pipelineConfigUpdates
+	}
+	return nil
+}
+
+func FetchInstanceConfigDetailRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	key := FetchInstanceConfigDetailResponseAction.Value
+	needFetchConfig := config.ServerConfigInstance.ResponseFlags[key]
+	if needFetchConfig {
+		strInstanceId := string(req.InstanceId)
+
+		instanceConfigUpdates, err := manager.GetInstanceConfigs(strInstanceId, req.InstanceConfigs, false)
+		if err != nil {
+			return common.SystemError(err)
+		}
+		res.InstanceConfigUpdates = instanceConfigUpdates
+	}
+	return nil
+}
+
+func HandleResponseFlags(res *proto.HeartbeatResponse) error {
+	for _, flag := range ResponseList {
+		err := flag.UpdateFlags(res)
+		if err != nil {
+			return common.SystemError(err)
+		}
+	}
+	return nil
+}
diff --git a/config_server/service/manager/state/server.go b/config_server/service/manager/state/server.go
new file mode 100644
index 0000000000..c9459037e5
--- /dev/null
+++ b/config_server/service/manager/state/server.go
@@ -0,0 +1,118 @@
+package state
+
+import (
+	"config-server/common"
+	"config-server/config"
+	"config-server/entity"
+	"config-server/manager"
+	proto "config-server/protov2"
+	"config-server/repository"
+)
+
+type ServerAction struct {
+	Base
+	Run func(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error
+}
+
+func (a ServerAction) Action(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	serverCapabilityType := a.Value
+	hasServerCapability := config.ServerConfigInstance.Capabilities[serverCapabilityType]
+
+	if hasServerCapability {
+		err := a.Run(req, res)
+		return common.SystemError(err)
+	}
+	return nil
+}
+
+func (a ServerAction) UpdateCapabilities(res *proto.HeartbeatResponse) error {
+	serverCapabilityType := a.Value
+	hasServerCapability := config.ServerConfigInstance.Capabilities[serverCapabilityType]
+
+	if hasServerCapability {
+		res.Capabilities = res.Capabilities | uint64(a.Code)
+	}
+	return nil
+}
+
+var (
+	ServerUnspecified            = Base{Code: 0, Value: "unspecified"}
+	RememberAttribute            = Base{Code: 1, Value: "rememberAttribute"}
+	RememberPipelineConfigStatus = Base{Code: 2, Value: "rememberPipelineConfigStatus"}
+	RememberInstanceConfigStatus = Base{Code: 4, Value: "rememberInstanceConfigStatus"}
+	RememberCustomCommandStatus  = Base{Code: 8, Value: "rememberCustomCommandStatus"}
+)
+
+var ServerActionList = []*ServerAction{
+	{
+		Base: ServerUnspecified,
+		Run:  UnspecifiedServerCapabilityRun,
+	},
+	{
+		Base: RememberAttribute,
+		Run:  RememberAttributeCapabilityRun,
+	},
+	{
+		Base: RememberPipelineConfigStatus,
+		Run:  RememberPipelineConfigStatusCapabilityRun,
+	},
+	{
+		Base: RememberInstanceConfigStatus,
+		Run:  RememberInstanceConfigStatusCapabilityRun,
+	},
+	{
+		Base: RememberCustomCommandStatus,
+		Run:  RememberCustomCommandStatusRun,
+	},
+}
+
+func UnspecifiedServerCapabilityRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	return nil
+}
+
+func RememberAttributeCapabilityRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	attributes := req.Attributes
+	if attributes == nil {
+		return nil
+	}
+	agent := &entity.Agent{
+		InstanceId: string(req.InstanceId),
+	}
+	agent.Attributes = entity.ParseProtoAgentAttributes2AgentAttributes(attributes)
+	err := repository.UpdateAgentById(agent, "attributes")
+	return common.SystemError(err)
+}
+
+func RememberPipelineConfigStatusCapabilityRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	configs := req.PipelineConfigs
+	if configs == nil {
+		return nil
+	}
+
+	err := manager.SavePipelineConfigStatus(configs, string(req.InstanceId))
+	return common.SystemError(err)
+}
+
+func RememberInstanceConfigStatusCapabilityRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	configs := req.InstanceConfigs
+	if configs == nil {
+		return nil
+	}
+
+	err := manager.SaveInstanceConfigStatus(configs, string(req.InstanceId))
+	return common.SystemError(err)
+}
+
+func RememberCustomCommandStatusRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
+	return nil
+}
+
+func HandleServerCapabilities(res *proto.HeartbeatResponse) error {
+	for _, action := range ServerActionList {
+		err := action.UpdateCapabilities(res)
+		if err != nil {
+			return common.SystemError(err)
+		}
+	}
+	return nil
+}
diff --git a/config_server/service/protov2/README.md b/config_server/service/protov2/README.md
new file mode 100644
index 0000000000..7995b9cecc
--- /dev/null
+++ b/config_server/service/protov2/README.md
@@ -0,0 +1,39 @@
+# Go Proto
+
+此为使用protoc命令生成go代码的文档
+
+## 预备条件
+
+安装好GO,并在环境变量中配置了`$GOROOT/bin`与`$GOPATH/bin`
+
+## 快速开始
+
+安装protoc(CentOs)
+
+```shell
+yum install -y protobuf-compiler
+```
+
+输入以下命令,若出现版本信息即安装成功
+
+```shell
+protoc --version
+# libprotoc 3.20.0
+```
+
+安装`protoc-gen-go`插件,默认路径为`$GOPATH/bin`
+
+```shell
+go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
+```
+
+进入`protocol/v2`文件夹
+
+```shell
+protoc --go_out=. agent.proto
+```
+
+```shell
+protoc --go_out=. user.proto
+```
+
diff --git a/config_server/service/protov2/agent.pb.go b/config_server/service/protov2/agent.pb.go
index aa3e46b51e..9911dd26fc 100644
--- a/config_server/service/protov2/agent.pb.go
+++ b/config_server/service/protov2/agent.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.34.2
-// 	protoc        v3.20.0
+// 	protoc-gen-go v1.35.1
+// 	protoc        v3.5.0
 // source: agent.proto
 
 package protov2
@@ -307,11 +307,9 @@ type AgentGroupTag struct {
 
 func (x *AgentGroupTag) Reset() {
 	*x = AgentGroupTag{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[0]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_agent_proto_msgTypes[0]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *AgentGroupTag) String() string {
@@ -322,7 +320,7 @@ func (*AgentGroupTag) ProtoMessage() {}
 
 func (x *AgentGroupTag) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_proto_msgTypes[0]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -365,11 +363,9 @@ type ConfigInfo struct {
 
 func (x *ConfigInfo) Reset() {
 	*x = ConfigInfo{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[1]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_agent_proto_msgTypes[1]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *ConfigInfo) String() string {
@@ -380,7 +376,7 @@ func (*ConfigInfo) ProtoMessage() {}
 
 func (x *ConfigInfo) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_proto_msgTypes[1]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -437,11 +433,9 @@ type CommandInfo struct {
 
 func (x *CommandInfo) Reset() {
 	*x = CommandInfo{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[2]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_agent_proto_msgTypes[2]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *CommandInfo) String() string {
@@ -452,7 +446,7 @@ func (*CommandInfo) ProtoMessage() {}
 
 func (x *CommandInfo) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_proto_msgTypes[2]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -509,11 +503,9 @@ type AgentAttributes struct {
 
 func (x *AgentAttributes) Reset() {
 	*x = AgentAttributes{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[3]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_agent_proto_msgTypes[3]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *AgentAttributes) String() string {
@@ -524,7 +516,7 @@ func (*AgentAttributes) ProtoMessage() {}
 
 func (x *AgentAttributes) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_proto_msgTypes[3]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -591,11 +583,9 @@ type HeartbeatRequest struct {
 
 func (x *HeartbeatRequest) Reset() {
 	*x = HeartbeatRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[4]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_agent_proto_msgTypes[4]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *HeartbeatRequest) String() string {
@@ -606,7 +596,7 @@ func (*HeartbeatRequest) ProtoMessage() {}
 
 func (x *HeartbeatRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_proto_msgTypes[4]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -732,11 +722,9 @@ type ConfigDetail struct {
 
 func (x *ConfigDetail) Reset() {
 	*x = ConfigDetail{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[5]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_agent_proto_msgTypes[5]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *ConfigDetail) String() string {
@@ -747,7 +735,7 @@ func (*ConfigDetail) ProtoMessage() {}
 
 func (x *ConfigDetail) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_proto_msgTypes[5]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -796,11 +784,9 @@ type CommandDetail struct {
 
 func (x *CommandDetail) Reset() {
 	*x = CommandDetail{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[6]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_agent_proto_msgTypes[6]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *CommandDetail) String() string {
@@ -811,7 +797,7 @@ func (*CommandDetail) ProtoMessage() {}
 
 func (x *CommandDetail) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_proto_msgTypes[6]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -872,11 +858,9 @@ type HeartbeatResponse struct {
 
 func (x *HeartbeatResponse) Reset() {
 	*x = HeartbeatResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[7]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_agent_proto_msgTypes[7]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *HeartbeatResponse) String() string {
@@ -887,7 +871,7 @@ func (*HeartbeatResponse) ProtoMessage() {}
 
 func (x *HeartbeatResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_proto_msgTypes[7]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -973,11 +957,9 @@ type FetchConfigRequest struct {
 
 func (x *FetchConfigRequest) Reset() {
 	*x = FetchConfigRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[8]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_agent_proto_msgTypes[8]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *FetchConfigRequest) String() string {
@@ -988,7 +970,7 @@ func (*FetchConfigRequest) ProtoMessage() {}
 
 func (x *FetchConfigRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_proto_msgTypes[8]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1037,11 +1019,9 @@ type FetchConfigResponse struct {
 
 func (x *FetchConfigResponse) Reset() {
 	*x = FetchConfigResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[9]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_agent_proto_msgTypes[9]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *FetchConfigResponse) String() string {
@@ -1052,7 +1032,7 @@ func (*FetchConfigResponse) ProtoMessage() {}
 
 func (x *FetchConfigResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_proto_msgTypes[9]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1099,11 +1079,9 @@ type CommonResponse struct {
 
 func (x *CommonResponse) Reset() {
 	*x = CommonResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_agent_proto_msgTypes[10]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_agent_proto_msgTypes[10]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *CommonResponse) String() string {
@@ -1114,7 +1092,7 @@ func (*CommonResponse) ProtoMessage() {}
 
 func (x *CommonResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_agent_proto_msgTypes[10]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1375,140 +1353,6 @@ func file_agent_proto_init() {
 	if File_agent_proto != nil {
 		return
 	}
-	if !protoimpl.UnsafeEnabled {
-		file_agent_proto_msgTypes[0].Exporter = func(v any, i int) any {
-			switch v := v.(*AgentGroupTag); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[1].Exporter = func(v any, i int) any {
-			switch v := v.(*ConfigInfo); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[2].Exporter = func(v any, i int) any {
-			switch v := v.(*CommandInfo); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[3].Exporter = func(v any, i int) any {
-			switch v := v.(*AgentAttributes); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[4].Exporter = func(v any, i int) any {
-			switch v := v.(*HeartbeatRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[5].Exporter = func(v any, i int) any {
-			switch v := v.(*ConfigDetail); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[6].Exporter = func(v any, i int) any {
-			switch v := v.(*CommandDetail); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[7].Exporter = func(v any, i int) any {
-			switch v := v.(*HeartbeatResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[8].Exporter = func(v any, i int) any {
-			switch v := v.(*FetchConfigRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[9].Exporter = func(v any, i int) any {
-			switch v := v.(*FetchConfigResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_agent_proto_msgTypes[10].Exporter = func(v any, i int) any {
-			switch v := v.(*CommonResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
diff --git a/config_server/service/protov2/user.pb.go b/config_server/service/protov2/user.pb.go
index 951367b407..89fd597edc 100644
--- a/config_server/service/protov2/user.pb.go
+++ b/config_server/service/protov2/user.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.34.2
-// 	protoc        v3.20.0
+// 	protoc-gen-go v1.35.1
+// 	protoc        v3.5.0
 // source: user.proto
 
 package protov2
@@ -25,21 +25,22 @@ type Agent struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Capabilities  uint64           `protobuf:"varint,1,opt,name=capabilities,proto3" json:"capabilities,omitempty"`                       // Bitmask of flags defined by AgentCapabilities enum
-	InstanceId    []byte           `protobuf:"bytes,2,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"`          // Required, Agent's unique identification, consistent throughout the process lifecycle
-	AgentType     string           `protobuf:"bytes,3,opt,name=agent_type,json=agentType,proto3" json:"agent_type,omitempty"`             // Required, Agent's type(ilogtail, ..)
-	Attributes    *AgentAttributes `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"`                            // Agent's basic attributes
-	RunningStatus string           `protobuf:"bytes,5,opt,name=running_status,json=runningStatus,proto3" json:"running_status,omitempty"` // Human readable running status
-	StartupTime   int64            `protobuf:"varint,6,opt,name=startup_time,json=startupTime,proto3" json:"startup_time,omitempty"`      // Required, Agent's startup time
+	Capabilities    uint64           `protobuf:"varint,1,opt,name=capabilities,proto3" json:"capabilities,omitempty"`                             // Bitmask of flags defined by AgentCapabilities enum
+	InstanceId      []byte           `protobuf:"bytes,2,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"`                // Required, Agent's unique identification, consistent throughout the process lifecycle
+	AgentType       string           `protobuf:"bytes,3,opt,name=agent_type,json=agentType,proto3" json:"agent_type,omitempty"`                   // Required, Agent's type(ilogtail, ..)
+	Attributes      *AgentAttributes `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"`                                  // Agent's basic attributes
+	RunningStatus   string           `protobuf:"bytes,5,opt,name=running_status,json=runningStatus,proto3" json:"running_status,omitempty"`       // Human readable running status
+	StartupTime     int64            `protobuf:"varint,6,opt,name=startup_time,json=startupTime,proto3" json:"startup_time,omitempty"`            // Required, Agent's startup time
+	PipelineConfigs []*ConfigInfo    `protobuf:"bytes,7,rep,name=pipeline_configs,json=pipelineConfigs,proto3" json:"pipeline_configs,omitempty"` // Information about the current PIPELINE_CONFIG held by the Agent
+	InstanceConfigs []*ConfigInfo    `protobuf:"bytes,8,rep,name=instance_configs,json=instanceConfigs,proto3" json:"instance_configs,omitempty"` // Information about the current AGENT_CONFIG held by the Agent
+	CustomCommands  []*CommandInfo   `protobuf:"bytes,9,rep,name=custom_commands,json=customCommands,proto3" json:"custom_commands,omitempty"`    // Information about command history
 }
 
 func (x *Agent) Reset() {
 	*x = Agent{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[0]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[0]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *Agent) String() string {
@@ -50,7 +51,7 @@ func (*Agent) ProtoMessage() {}
 
 func (x *Agent) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[0]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -107,6 +108,27 @@ func (x *Agent) GetStartupTime() int64 {
 	return 0
 }
 
+func (x *Agent) GetPipelineConfigs() []*ConfigInfo {
+	if x != nil {
+		return x.PipelineConfigs
+	}
+	return nil
+}
+
+func (x *Agent) GetInstanceConfigs() []*ConfigInfo {
+	if x != nil {
+		return x.InstanceConfigs
+	}
+	return nil
+}
+
+func (x *Agent) GetCustomCommands() []*CommandInfo {
+	if x != nil {
+		return x.CustomCommands
+	}
+	return nil
+}
+
 type AgentConfigStatus struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -119,11 +141,9 @@ type AgentConfigStatus struct {
 
 func (x *AgentConfigStatus) Reset() {
 	*x = AgentConfigStatus{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[1]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[1]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *AgentConfigStatus) String() string {
@@ -134,7 +154,7 @@ func (*AgentConfigStatus) ProtoMessage() {}
 
 func (x *AgentConfigStatus) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[1]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -181,11 +201,9 @@ type CreateAgentGroupRequest struct {
 
 func (x *CreateAgentGroupRequest) Reset() {
 	*x = CreateAgentGroupRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[2]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[2]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *CreateAgentGroupRequest) String() string {
@@ -196,7 +214,7 @@ func (*CreateAgentGroupRequest) ProtoMessage() {}
 
 func (x *CreateAgentGroupRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[2]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -236,11 +254,9 @@ type CreateAgentGroupResponse struct {
 
 func (x *CreateAgentGroupResponse) Reset() {
 	*x = CreateAgentGroupResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[3]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[3]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *CreateAgentGroupResponse) String() string {
@@ -251,7 +267,7 @@ func (*CreateAgentGroupResponse) ProtoMessage() {}
 
 func (x *CreateAgentGroupResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[3]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -291,11 +307,9 @@ type UpdateAgentGroupRequest struct {
 
 func (x *UpdateAgentGroupRequest) Reset() {
 	*x = UpdateAgentGroupRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[4]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[4]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *UpdateAgentGroupRequest) String() string {
@@ -306,7 +320,7 @@ func (*UpdateAgentGroupRequest) ProtoMessage() {}
 
 func (x *UpdateAgentGroupRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[4]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -346,11 +360,9 @@ type UpdateAgentGroupResponse struct {
 
 func (x *UpdateAgentGroupResponse) Reset() {
 	*x = UpdateAgentGroupResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[5]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[5]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *UpdateAgentGroupResponse) String() string {
@@ -361,7 +373,7 @@ func (*UpdateAgentGroupResponse) ProtoMessage() {}
 
 func (x *UpdateAgentGroupResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[5]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -401,11 +413,9 @@ type DeleteAgentGroupRequest struct {
 
 func (x *DeleteAgentGroupRequest) Reset() {
 	*x = DeleteAgentGroupRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[6]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[6]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *DeleteAgentGroupRequest) String() string {
@@ -416,7 +426,7 @@ func (*DeleteAgentGroupRequest) ProtoMessage() {}
 
 func (x *DeleteAgentGroupRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[6]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -456,11 +466,9 @@ type DeleteAgentGroupResponse struct {
 
 func (x *DeleteAgentGroupResponse) Reset() {
 	*x = DeleteAgentGroupResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[7]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[7]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *DeleteAgentGroupResponse) String() string {
@@ -471,7 +479,7 @@ func (*DeleteAgentGroupResponse) ProtoMessage() {}
 
 func (x *DeleteAgentGroupResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[7]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -511,11 +519,9 @@ type GetAgentGroupRequest struct {
 
 func (x *GetAgentGroupRequest) Reset() {
 	*x = GetAgentGroupRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[8]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[8]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *GetAgentGroupRequest) String() string {
@@ -526,7 +532,7 @@ func (*GetAgentGroupRequest) ProtoMessage() {}
 
 func (x *GetAgentGroupRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[8]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -567,11 +573,9 @@ type GetAgentGroupResponse struct {
 
 func (x *GetAgentGroupResponse) Reset() {
 	*x = GetAgentGroupResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[9]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[9]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *GetAgentGroupResponse) String() string {
@@ -582,7 +586,7 @@ func (*GetAgentGroupResponse) ProtoMessage() {}
 
 func (x *GetAgentGroupResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[9]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -628,11 +632,9 @@ type ListAgentGroupsRequest struct {
 
 func (x *ListAgentGroupsRequest) Reset() {
 	*x = ListAgentGroupsRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[10]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[10]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *ListAgentGroupsRequest) String() string {
@@ -643,7 +645,7 @@ func (*ListAgentGroupsRequest) ProtoMessage() {}
 
 func (x *ListAgentGroupsRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[10]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -677,11 +679,9 @@ type ListAgentGroupsResponse struct {
 
 func (x *ListAgentGroupsResponse) Reset() {
 	*x = ListAgentGroupsResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[11]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[11]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *ListAgentGroupsResponse) String() string {
@@ -692,7 +692,7 @@ func (*ListAgentGroupsResponse) ProtoMessage() {}
 
 func (x *ListAgentGroupsResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[11]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -741,11 +741,9 @@ type CreateConfigRequest struct {
 
 func (x *CreateConfigRequest) Reset() {
 	*x = CreateConfigRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[12]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[12]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *CreateConfigRequest) String() string {
@@ -756,7 +754,7 @@ func (*CreateConfigRequest) ProtoMessage() {}
 
 func (x *CreateConfigRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[12]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -796,11 +794,9 @@ type CreateConfigResponse struct {
 
 func (x *CreateConfigResponse) Reset() {
 	*x = CreateConfigResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[13]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[13]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *CreateConfigResponse) String() string {
@@ -811,7 +807,7 @@ func (*CreateConfigResponse) ProtoMessage() {}
 
 func (x *CreateConfigResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[13]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -853,11 +849,9 @@ type UpdateConfigRequest struct {
 
 func (x *UpdateConfigRequest) Reset() {
 	*x = UpdateConfigRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[14]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[14]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *UpdateConfigRequest) String() string {
@@ -868,7 +862,7 @@ func (*UpdateConfigRequest) ProtoMessage() {}
 
 func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[14]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -908,11 +902,9 @@ type UpdateConfigResponse struct {
 
 func (x *UpdateConfigResponse) Reset() {
 	*x = UpdateConfigResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[15]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[15]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *UpdateConfigResponse) String() string {
@@ -923,7 +915,7 @@ func (*UpdateConfigResponse) ProtoMessage() {}
 
 func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[15]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -965,11 +957,9 @@ type DeleteConfigRequest struct {
 
 func (x *DeleteConfigRequest) Reset() {
 	*x = DeleteConfigRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[16]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[16]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *DeleteConfigRequest) String() string {
@@ -980,7 +970,7 @@ func (*DeleteConfigRequest) ProtoMessage() {}
 
 func (x *DeleteConfigRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[16]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1020,11 +1010,9 @@ type DeleteConfigResponse struct {
 
 func (x *DeleteConfigResponse) Reset() {
 	*x = DeleteConfigResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[17]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[17]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *DeleteConfigResponse) String() string {
@@ -1035,7 +1023,7 @@ func (*DeleteConfigResponse) ProtoMessage() {}
 
 func (x *DeleteConfigResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[17]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1077,11 +1065,9 @@ type GetConfigRequest struct {
 
 func (x *GetConfigRequest) Reset() {
 	*x = GetConfigRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[18]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[18]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *GetConfigRequest) String() string {
@@ -1092,7 +1078,7 @@ func (*GetConfigRequest) ProtoMessage() {}
 
 func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[18]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1133,11 +1119,9 @@ type GetConfigResponse struct {
 
 func (x *GetConfigResponse) Reset() {
 	*x = GetConfigResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[19]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[19]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *GetConfigResponse) String() string {
@@ -1148,7 +1132,7 @@ func (*GetConfigResponse) ProtoMessage() {}
 
 func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[19]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1197,11 +1181,9 @@ type GetConfigStatusListRequest struct {
 
 func (x *GetConfigStatusListRequest) Reset() {
 	*x = GetConfigStatusListRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[20]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[20]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *GetConfigStatusListRequest) String() string {
@@ -1212,7 +1194,7 @@ func (*GetConfigStatusListRequest) ProtoMessage() {}
 
 func (x *GetConfigStatusListRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[20]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1253,11 +1235,9 @@ type GetConfigStatusListResponse struct {
 
 func (x *GetConfigStatusListResponse) Reset() {
 	*x = GetConfigStatusListResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[21]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[21]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *GetConfigStatusListResponse) String() string {
@@ -1268,7 +1248,7 @@ func (*GetConfigStatusListResponse) ProtoMessage() {}
 
 func (x *GetConfigStatusListResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[21]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1316,11 +1296,9 @@ type ListConfigsRequest struct {
 
 func (x *ListConfigsRequest) Reset() {
 	*x = ListConfigsRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[22]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[22]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *ListConfigsRequest) String() string {
@@ -1331,7 +1309,7 @@ func (*ListConfigsRequest) ProtoMessage() {}
 
 func (x *ListConfigsRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[22]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1365,11 +1343,9 @@ type ListConfigsResponse struct {
 
 func (x *ListConfigsResponse) Reset() {
 	*x = ListConfigsResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[23]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[23]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *ListConfigsResponse) String() string {
@@ -1380,7 +1356,7 @@ func (*ListConfigsResponse) ProtoMessage() {}
 
 func (x *ListConfigsResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[23]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1430,11 +1406,9 @@ type ApplyConfigToAgentGroupRequest struct {
 
 func (x *ApplyConfigToAgentGroupRequest) Reset() {
 	*x = ApplyConfigToAgentGroupRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[24]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[24]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *ApplyConfigToAgentGroupRequest) String() string {
@@ -1445,7 +1419,7 @@ func (*ApplyConfigToAgentGroupRequest) ProtoMessage() {}
 
 func (x *ApplyConfigToAgentGroupRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[24]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1492,11 +1466,9 @@ type ApplyConfigToAgentGroupResponse struct {
 
 func (x *ApplyConfigToAgentGroupResponse) Reset() {
 	*x = ApplyConfigToAgentGroupResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[25]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[25]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *ApplyConfigToAgentGroupResponse) String() string {
@@ -1507,7 +1479,7 @@ func (*ApplyConfigToAgentGroupResponse) ProtoMessage() {}
 
 func (x *ApplyConfigToAgentGroupResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[25]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1550,11 +1522,9 @@ type RemoveConfigFromAgentGroupRequest struct {
 
 func (x *RemoveConfigFromAgentGroupRequest) Reset() {
 	*x = RemoveConfigFromAgentGroupRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[26]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[26]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *RemoveConfigFromAgentGroupRequest) String() string {
@@ -1565,7 +1535,7 @@ func (*RemoveConfigFromAgentGroupRequest) ProtoMessage() {}
 
 func (x *RemoveConfigFromAgentGroupRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[26]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1612,11 +1582,9 @@ type RemoveConfigFromAgentGroupResponse struct {
 
 func (x *RemoveConfigFromAgentGroupResponse) Reset() {
 	*x = RemoveConfigFromAgentGroupResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[27]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[27]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *RemoveConfigFromAgentGroupResponse) String() string {
@@ -1627,7 +1595,7 @@ func (*RemoveConfigFromAgentGroupResponse) ProtoMessage() {}
 
 func (x *RemoveConfigFromAgentGroupResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[27]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1669,11 +1637,9 @@ type GetAppliedConfigsForAgentGroupRequest struct {
 
 func (x *GetAppliedConfigsForAgentGroupRequest) Reset() {
 	*x = GetAppliedConfigsForAgentGroupRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[28]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[28]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *GetAppliedConfigsForAgentGroupRequest) String() string {
@@ -1684,7 +1650,7 @@ func (*GetAppliedConfigsForAgentGroupRequest) ProtoMessage() {}
 
 func (x *GetAppliedConfigsForAgentGroupRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[28]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1725,11 +1691,9 @@ type GetAppliedConfigsForAgentGroupResponse struct {
 
 func (x *GetAppliedConfigsForAgentGroupResponse) Reset() {
 	*x = GetAppliedConfigsForAgentGroupResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[29]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[29]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *GetAppliedConfigsForAgentGroupResponse) String() string {
@@ -1740,7 +1704,7 @@ func (*GetAppliedConfigsForAgentGroupResponse) ProtoMessage() {}
 
 func (x *GetAppliedConfigsForAgentGroupResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[29]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1789,11 +1753,9 @@ type GetAppliedAgentGroupsRequest struct {
 
 func (x *GetAppliedAgentGroupsRequest) Reset() {
 	*x = GetAppliedAgentGroupsRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[30]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[30]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *GetAppliedAgentGroupsRequest) String() string {
@@ -1804,7 +1766,7 @@ func (*GetAppliedAgentGroupsRequest) ProtoMessage() {}
 
 func (x *GetAppliedAgentGroupsRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[30]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1845,11 +1807,9 @@ type GetAppliedAgentGroupsResponse struct {
 
 func (x *GetAppliedAgentGroupsResponse) Reset() {
 	*x = GetAppliedAgentGroupsResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[31]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[31]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *GetAppliedAgentGroupsResponse) String() string {
@@ -1860,7 +1820,7 @@ func (*GetAppliedAgentGroupsResponse) ProtoMessage() {}
 
 func (x *GetAppliedAgentGroupsResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[31]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1907,11 +1867,9 @@ type ListAgentsRequest struct {
 
 func (x *ListAgentsRequest) Reset() {
 	*x = ListAgentsRequest{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[32]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[32]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *ListAgentsRequest) String() string {
@@ -1922,7 +1880,7 @@ func (*ListAgentsRequest) ProtoMessage() {}
 
 func (x *ListAgentsRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[32]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -1963,11 +1921,9 @@ type ListAgentsResponse struct {
 
 func (x *ListAgentsResponse) Reset() {
 	*x = ListAgentsResponse{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_user_proto_msgTypes[33]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
+	mi := &file_user_proto_msgTypes[33]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
 }
 
 func (x *ListAgentsResponse) String() string {
@@ -1978,7 +1934,7 @@ func (*ListAgentsResponse) ProtoMessage() {}
 
 func (x *ListAgentsResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_user_proto_msgTypes[33]
-	if protoimpl.UnsafeEnabled && x != nil {
+	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
 			ms.StoreMessageInfo(mi)
@@ -2018,7 +1974,7 @@ var File_user_proto protoreflect.FileDescriptor
 
 var file_user_proto_rawDesc = []byte{
 	0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0b, 0x61, 0x67,
-	0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe7, 0x01, 0x0a, 0x05, 0x41, 0x67,
+	0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8e, 0x03, 0x0a, 0x05, 0x41, 0x67,
 	0x65, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
 	0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62,
 	0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61,
@@ -2033,251 +1989,262 @@ var file_user_proto_rawDesc = []byte{
 	0x09, 0x52, 0x0d, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
 	0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65,
 	0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x54,
-	0x69, 0x6d, 0x65, 0x22, 0x68, 0x0a, 0x11, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x06,
-	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x69, 0x0a,
-	0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
-	0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74,
-	0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41,
-	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52, 0x0a, 0x61, 0x67,
-	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x73, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61,
-	0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
-	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43,
-	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63,
-	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x0a,
-	0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
-	0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74,
-	0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41,
-	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52, 0x0a, 0x61, 0x67,
-	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x73, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61,
-	0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
-	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43,
-	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63,
-	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x57, 0x0a,
-	0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
-	0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70,
-	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f,
-	0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x73, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
-	0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
-	0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x54, 0x0a, 0x14, 0x47,
-	0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d,
-	0x65, 0x22, 0xa1, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
+	0x69, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x10, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x70, 0x69, 0x70, 0x65,
+	0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x36, 0x0a, 0x10, 0x69,
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18,
+	0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e,
+	0x66, 0x6f, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6f,
+	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x43,
+	0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74,
+	0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x68, 0x0a, 0x11, 0x41, 0x67,
+	0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
+	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74,
+	0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x22, 0x69, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67,
+	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x2f,
+	0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
+	0x54, 0x61, 0x67, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22,
+	0x73, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
 	0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72,
 	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
 	0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f,
 	0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20,
 	0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
 	0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72,
-	0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e,
-	0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74,
-	0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x37, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65,
-	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67,
+	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
 	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0xa5,
-	0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
-	0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f,
-	0x75, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e,
-	0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74,
-	0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x68, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
-	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
-	0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x0d,
-	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
-	0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
-	0x22, 0x6f, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
-	0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x22, 0x68, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d,
-	0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x6f, 0x0a, 0x14, 0x55,
-	0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f,
-	0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f,
-	0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x0a, 0x13,
-	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e,
-	0x61, 0x6d, 0x65, 0x22, 0x6f, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72,
+	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x2f,
+	0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
+	0x54, 0x61, 0x67, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22,
+	0x73, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
+	0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72,
 	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
 	0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f,
 	0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20,
 	0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
 	0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa0, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74,
-	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d,
-	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a,
-	0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d,
-	0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x5c, 0x0a, 0x1a, 0x47,
-	0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4c, 0x69,
-	0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74,
-	0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69,
-	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0xba, 0x01, 0x0a, 0x1b, 0x47, 0x65,
-	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4c, 0x69, 0x73,
-	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x57, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67,
+	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d,
+	0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x73, 0x0a,
+	0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
 	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72,
 	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d,
 	0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
 	0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
 	0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x42, 0x0a, 0x13, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
-	0x12, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x52, 0x11, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x33, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
-	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0xa4, 0x01, 0x0a, 0x13,
-	0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f,
-	0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f,
-	0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0e,
-	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03,
-	0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74,
-	0x61, 0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69,
-	0x6c, 0x73, 0x22, 0x7f, 0x0a, 0x1e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71,
+	0x73, 0x65, 0x22, 0x54, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
+	0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f,
+	0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67,
+	0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa1, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74,
+	0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
+	0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x0b, 0x61,
+	0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67,
+	0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x37, 0x0a, 0x16,
+	0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0xa5, 0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67,
+	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64,
+	0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
+	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d,
+	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x0c, 0x61, 0x67,
+	0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67,
+	0x52, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x68, 0x0a,
+	0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71,
 	0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
 	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61,
-	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61,
-	0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e,
-	0x61, 0x6d, 0x65, 0x22, 0x7a, 0x0a, 0x1f, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f,
-	0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f,
-	0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52,
-	0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
-	0x82, 0x01, 0x0a, 0x21, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x46, 0x72, 0x6f, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e,
-	0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e,
-	0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70,
-	0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7d, 0x0a, 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f,
-	0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
+	0x74, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65,
+	0x74, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x6f, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38,
+	0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x68, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61,
+	0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x32,
+	0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65,
+	0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
+	0x69, 0x6c, 0x22, 0x6f, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
 	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
 	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
 	0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
 	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
 	0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x22, 0x65, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65,
-	0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x46, 0x6f, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74,
-	0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
-	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67,
-	0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x26, 0x47,
-	0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73,
-	0x46, 0x6f, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73,
+	0x6e, 0x73, 0x65, 0x22, 0x55, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x6f, 0x0a, 0x14, 0x44, 0x65,
+	0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
+	0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x0a, 0x10, 0x47,
+	0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f,
+	0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22,
+	0xa0, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73,
 	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
 	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65,
 	0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72,
 	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e,
 	0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e,
-	0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21,
-	0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04,
-	0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65,
-	0x73, 0x22, 0x5e, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x41,
-	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64,
-	0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d,
-	0x65, 0x22, 0xa4, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64,
-	0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
+	0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32,
+	0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65,
+	0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
+	0x69, 0x6c, 0x22, 0x5c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12,
+	0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64,
+	0x22, 0xba, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12,
+	0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f,
+	0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+	0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x13, 0x61, 0x67, 0x65,
+	0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x11, 0x61, 0x67, 0x65, 0x6e,
+	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x33, 0x0a,
+	0x12, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
 	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f,
-	0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f,
-	0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x11,
-	0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
-	0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
-	0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74,
-	0x41, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
+	0x49, 0x64, 0x22, 0xa4, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65,
+	0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x7f, 0x0a, 0x1e, 0x41, 0x70, 0x70,
+	0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47,
+	0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
+	0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67,
+	0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7a, 0x0a, 0x1f, 0x41, 0x70,
+	0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74,
+	0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a,
 	0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a,
-	0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x8d, 0x01, 0x0a, 0x12,
-	0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
-	0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x06, 0x61,
-	0x67, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x06, 0x2e, 0x41, 0x67,
-	0x65, 0x6e, 0x74, 0x52, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x0b, 0x5a, 0x09, 0x2f,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x76, 0x32, 0x3b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f,
+	0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x21, 0x52, 0x65, 0x6d, 0x6f, 0x76,
+	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x74,
+	0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
+	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a,
+	0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7d, 0x0a, 0x22, 0x52,
+	0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x41,
+	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64,
+	0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
+	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d,
+	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x65, 0x0a, 0x25, 0x47, 0x65,
+	0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x46,
+	0x6f, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d,
+	0x65, 0x22, 0xa4, 0x01, 0x0a, 0x26, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x46, 0x6f, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47,
+	0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
+	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63,
+	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
+	0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x5e, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x41,
+	0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
+	0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74,
+	0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f,
+	0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f,
+	0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22,
+	0x51, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61,
+	0x6d, 0x65, 0x22, 0x8d, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74,
+	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d,
+	0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x1e, 0x0a, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x06, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x61, 0x67, 0x65, 0x6e,
+	0x74, 0x73, 0x42, 0x0b, 0x5a, 0x09, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x76, 0x32, 0x3b, 0x62,
+	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -2329,45 +2296,50 @@ var file_user_proto_goTypes = []any{
 	(*ListAgentsRequest)(nil),                      // 32: ListAgentsRequest
 	(*ListAgentsResponse)(nil),                     // 33: ListAgentsResponse
 	(*AgentAttributes)(nil),                        // 34: AgentAttributes
-	(ConfigStatus)(0),                              // 35: ConfigStatus
-	(*AgentGroupTag)(nil),                          // 36: AgentGroupTag
-	(*CommonResponse)(nil),                         // 37: CommonResponse
-	(*ConfigDetail)(nil),                           // 38: ConfigDetail
+	(*ConfigInfo)(nil),                             // 35: ConfigInfo
+	(*CommandInfo)(nil),                            // 36: CommandInfo
+	(ConfigStatus)(0),                              // 37: ConfigStatus
+	(*AgentGroupTag)(nil),                          // 38: AgentGroupTag
+	(*CommonResponse)(nil),                         // 39: CommonResponse
+	(*ConfigDetail)(nil),                           // 40: ConfigDetail
 }
 var file_user_proto_depIdxs = []int32{
 	34, // 0: Agent.attributes:type_name -> AgentAttributes
-	35, // 1: AgentConfigStatus.status:type_name -> ConfigStatus
-	36, // 2: CreateAgentGroupRequest.agent_group:type_name -> AgentGroupTag
-	37, // 3: CreateAgentGroupResponse.common_response:type_name -> CommonResponse
-	36, // 4: UpdateAgentGroupRequest.agent_group:type_name -> AgentGroupTag
-	37, // 5: UpdateAgentGroupResponse.common_response:type_name -> CommonResponse
-	37, // 6: DeleteAgentGroupResponse.common_response:type_name -> CommonResponse
-	37, // 7: GetAgentGroupResponse.common_response:type_name -> CommonResponse
-	36, // 8: GetAgentGroupResponse.agent_group:type_name -> AgentGroupTag
-	37, // 9: ListAgentGroupsResponse.common_response:type_name -> CommonResponse
-	36, // 10: ListAgentGroupsResponse.agent_groups:type_name -> AgentGroupTag
-	38, // 11: CreateConfigRequest.config_detail:type_name -> ConfigDetail
-	37, // 12: CreateConfigResponse.common_response:type_name -> CommonResponse
-	38, // 13: UpdateConfigRequest.config_detail:type_name -> ConfigDetail
-	37, // 14: UpdateConfigResponse.common_response:type_name -> CommonResponse
-	37, // 15: DeleteConfigResponse.common_response:type_name -> CommonResponse
-	37, // 16: GetConfigResponse.common_response:type_name -> CommonResponse
-	38, // 17: GetConfigResponse.config_detail:type_name -> ConfigDetail
-	37, // 18: GetConfigStatusListResponse.common_response:type_name -> CommonResponse
-	1,  // 19: GetConfigStatusListResponse.agent_config_status:type_name -> AgentConfigStatus
-	37, // 20: ListConfigsResponse.common_response:type_name -> CommonResponse
-	38, // 21: ListConfigsResponse.config_details:type_name -> ConfigDetail
-	37, // 22: ApplyConfigToAgentGroupResponse.common_response:type_name -> CommonResponse
-	37, // 23: RemoveConfigFromAgentGroupResponse.common_response:type_name -> CommonResponse
-	37, // 24: GetAppliedConfigsForAgentGroupResponse.common_response:type_name -> CommonResponse
-	37, // 25: GetAppliedAgentGroupsResponse.common_response:type_name -> CommonResponse
-	37, // 26: ListAgentsResponse.common_response:type_name -> CommonResponse
-	0,  // 27: ListAgentsResponse.agents:type_name -> Agent
-	28, // [28:28] is the sub-list for method output_type
-	28, // [28:28] is the sub-list for method input_type
-	28, // [28:28] is the sub-list for extension type_name
-	28, // [28:28] is the sub-list for extension extendee
-	0,  // [0:28] is the sub-list for field type_name
+	35, // 1: Agent.pipeline_configs:type_name -> ConfigInfo
+	35, // 2: Agent.instance_configs:type_name -> ConfigInfo
+	36, // 3: Agent.custom_commands:type_name -> CommandInfo
+	37, // 4: AgentConfigStatus.status:type_name -> ConfigStatus
+	38, // 5: CreateAgentGroupRequest.agent_group:type_name -> AgentGroupTag
+	39, // 6: CreateAgentGroupResponse.common_response:type_name -> CommonResponse
+	38, // 7: UpdateAgentGroupRequest.agent_group:type_name -> AgentGroupTag
+	39, // 8: UpdateAgentGroupResponse.common_response:type_name -> CommonResponse
+	39, // 9: DeleteAgentGroupResponse.common_response:type_name -> CommonResponse
+	39, // 10: GetAgentGroupResponse.common_response:type_name -> CommonResponse
+	38, // 11: GetAgentGroupResponse.agent_group:type_name -> AgentGroupTag
+	39, // 12: ListAgentGroupsResponse.common_response:type_name -> CommonResponse
+	38, // 13: ListAgentGroupsResponse.agent_groups:type_name -> AgentGroupTag
+	40, // 14: CreateConfigRequest.config_detail:type_name -> ConfigDetail
+	39, // 15: CreateConfigResponse.common_response:type_name -> CommonResponse
+	40, // 16: UpdateConfigRequest.config_detail:type_name -> ConfigDetail
+	39, // 17: UpdateConfigResponse.common_response:type_name -> CommonResponse
+	39, // 18: DeleteConfigResponse.common_response:type_name -> CommonResponse
+	39, // 19: GetConfigResponse.common_response:type_name -> CommonResponse
+	40, // 20: GetConfigResponse.config_detail:type_name -> ConfigDetail
+	39, // 21: GetConfigStatusListResponse.common_response:type_name -> CommonResponse
+	1,  // 22: GetConfigStatusListResponse.agent_config_status:type_name -> AgentConfigStatus
+	39, // 23: ListConfigsResponse.common_response:type_name -> CommonResponse
+	40, // 24: ListConfigsResponse.config_details:type_name -> ConfigDetail
+	39, // 25: ApplyConfigToAgentGroupResponse.common_response:type_name -> CommonResponse
+	39, // 26: RemoveConfigFromAgentGroupResponse.common_response:type_name -> CommonResponse
+	39, // 27: GetAppliedConfigsForAgentGroupResponse.common_response:type_name -> CommonResponse
+	39, // 28: GetAppliedAgentGroupsResponse.common_response:type_name -> CommonResponse
+	39, // 29: ListAgentsResponse.common_response:type_name -> CommonResponse
+	0,  // 30: ListAgentsResponse.agents:type_name -> Agent
+	31, // [31:31] is the sub-list for method output_type
+	31, // [31:31] is the sub-list for method input_type
+	31, // [31:31] is the sub-list for extension type_name
+	31, // [31:31] is the sub-list for extension extendee
+	0,  // [0:31] is the sub-list for field type_name
 }
 
 func init() { file_user_proto_init() }
@@ -2376,416 +2348,6 @@ func file_user_proto_init() {
 		return
 	}
 	file_agent_proto_init()
-	if !protoimpl.UnsafeEnabled {
-		file_user_proto_msgTypes[0].Exporter = func(v any, i int) any {
-			switch v := v.(*Agent); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[1].Exporter = func(v any, i int) any {
-			switch v := v.(*AgentConfigStatus); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[2].Exporter = func(v any, i int) any {
-			switch v := v.(*CreateAgentGroupRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[3].Exporter = func(v any, i int) any {
-			switch v := v.(*CreateAgentGroupResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[4].Exporter = func(v any, i int) any {
-			switch v := v.(*UpdateAgentGroupRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[5].Exporter = func(v any, i int) any {
-			switch v := v.(*UpdateAgentGroupResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[6].Exporter = func(v any, i int) any {
-			switch v := v.(*DeleteAgentGroupRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[7].Exporter = func(v any, i int) any {
-			switch v := v.(*DeleteAgentGroupResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[8].Exporter = func(v any, i int) any {
-			switch v := v.(*GetAgentGroupRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[9].Exporter = func(v any, i int) any {
-			switch v := v.(*GetAgentGroupResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[10].Exporter = func(v any, i int) any {
-			switch v := v.(*ListAgentGroupsRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[11].Exporter = func(v any, i int) any {
-			switch v := v.(*ListAgentGroupsResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[12].Exporter = func(v any, i int) any {
-			switch v := v.(*CreateConfigRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[13].Exporter = func(v any, i int) any {
-			switch v := v.(*CreateConfigResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[14].Exporter = func(v any, i int) any {
-			switch v := v.(*UpdateConfigRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[15].Exporter = func(v any, i int) any {
-			switch v := v.(*UpdateConfigResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[16].Exporter = func(v any, i int) any {
-			switch v := v.(*DeleteConfigRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[17].Exporter = func(v any, i int) any {
-			switch v := v.(*DeleteConfigResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[18].Exporter = func(v any, i int) any {
-			switch v := v.(*GetConfigRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[19].Exporter = func(v any, i int) any {
-			switch v := v.(*GetConfigResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[20].Exporter = func(v any, i int) any {
-			switch v := v.(*GetConfigStatusListRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[21].Exporter = func(v any, i int) any {
-			switch v := v.(*GetConfigStatusListResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[22].Exporter = func(v any, i int) any {
-			switch v := v.(*ListConfigsRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[23].Exporter = func(v any, i int) any {
-			switch v := v.(*ListConfigsResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[24].Exporter = func(v any, i int) any {
-			switch v := v.(*ApplyConfigToAgentGroupRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[25].Exporter = func(v any, i int) any {
-			switch v := v.(*ApplyConfigToAgentGroupResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[26].Exporter = func(v any, i int) any {
-			switch v := v.(*RemoveConfigFromAgentGroupRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[27].Exporter = func(v any, i int) any {
-			switch v := v.(*RemoveConfigFromAgentGroupResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[28].Exporter = func(v any, i int) any {
-			switch v := v.(*GetAppliedConfigsForAgentGroupRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[29].Exporter = func(v any, i int) any {
-			switch v := v.(*GetAppliedConfigsForAgentGroupResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[30].Exporter = func(v any, i int) any {
-			switch v := v.(*GetAppliedAgentGroupsRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[31].Exporter = func(v any, i int) any {
-			switch v := v.(*GetAppliedAgentGroupsResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[32].Exporter = func(v any, i int) any {
-			switch v := v.(*ListAgentsRequest); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_user_proto_msgTypes[33].Exporter = func(v any, i int) any {
-			switch v := v.(*ListAgentsResponse); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
diff --git a/config_server/service/repository/agent.go b/config_server/service/repository/agent.go
index 1d63f77c0a..0c857a10f2 100644
--- a/config_server/service/repository/agent.go
+++ b/config_server/service/repository/agent.go
@@ -4,7 +4,6 @@ import (
 	"config-server/common"
 	"config-server/entity"
 	"config-server/store"
-	"gorm.io/gorm"
 )
 
 var s = store.S
@@ -32,27 +31,23 @@ func GetAllAgents(containPipelineConfigs bool, containInstanceConfigs bool) []en
 }
 
 func RemoveAgentById(instanceId string) error {
-	var tx *gorm.DB
-
-	tx = s.Db.Where("instance_id=?", instanceId).Delete(&entity.Agent{})
+	tx := s.Db.Where("instance_id=?", instanceId).Delete(&entity.Agent{})
 	if tx.RowsAffected != 1 {
 		return common.ServerErrorWithMsg("Agent failed to delete record %s", instanceId)
 	}
-	s.Db.Where("agent_instance_id=?", instanceId).Delete(&entity.AgentPipelineConfig{})
-	s.Db.Where("agent_instance_id=?", instanceId).Delete(&entity.AgentInstanceConfig{})
 	return nil
 }
 
 func UpdateAgentById(agent *entity.Agent, filed ...string) error {
 	if filed == nil {
-		row := s.Db.Model(agent).Updates(*agent).RowsAffected
-		if row != 1 {
-			return common.ServerErrorWithMsg("update agent error")
+		err := s.Db.Model(agent).Updates(*agent).Error
+		if err != nil {
+			return common.SystemError(err)
 		}
 	}
-	row := s.Db.Model(agent).Select(filed).Updates(*agent).RowsAffected
-	if row != 1 {
-		return common.ServerErrorWithMsg("update agent filed error")
+	err := s.Db.Model(agent).Select(filed).Updates(*agent).Error
+	if err != nil {
+		return common.SystemError(err)
 	}
 	return nil
 }
@@ -69,21 +64,3 @@ func ListAgentsByGroupName(groupName string) ([]*entity.Agent, error) {
 	}
 	return agentGroup.Agents, nil
 }
-
-func GetPipelineConfigStatusList(instanceId string) ([]*entity.AgentPipelineConfig, error) {
-	configs := make([]*entity.AgentPipelineConfig, 0)
-	err := s.Db.Where("agent_instance_id=?", instanceId).Find(&configs).Error
-	if err != nil {
-		return nil, err
-	}
-	return configs, err
-}
-
-func GetInstanceConfigStatusList(instanceId string) ([]*entity.AgentInstanceConfig, error) {
-	configs := make([]*entity.AgentInstanceConfig, 0)
-	err := s.Db.Where("agent_instance_id=?", instanceId).Find(&configs).Error
-	if err != nil {
-		return nil, err
-	}
-	return configs, err
-}
diff --git a/config_server/service/repository/instance_config.go b/config_server/service/repository/instance_config.go
index e9cfba66a5..5dd6535b6b 100644
--- a/config_server/service/repository/instance_config.go
+++ b/config_server/service/repository/instance_config.go
@@ -5,6 +5,20 @@ import (
 	"config-server/entity"
 )
 
+func GetInstanceConfigByNames(names ...string) ([]*entity.InstanceConfig, error) {
+	instanceConfigs := make([]*entity.InstanceConfig, 0)
+	row := s.Db.Where("name in (?)", names).Find(&instanceConfigs).RowsAffected
+	if row != int64(len(names)) {
+		return nil, common.ServerErrorWithMsg("instanceNames=%s can not be found", names)
+	}
+	return instanceConfigs, nil
+}
+
+func GetInstanceConfigsByAgent(agent *entity.Agent) error {
+	err := s.Db.Preload("Tags.InstanceConfigs").Where("instance_id=?", agent.InstanceId).Find(agent).Error
+	return common.SystemError(err)
+}
+
 func CreateInstanceConfig(config *entity.InstanceConfig) error {
 	row := s.Db.Create(config).RowsAffected
 	if row != 1 {
@@ -52,33 +66,6 @@ func CreateInstanceConfigForAgentGroup(groupName string, configName string) erro
 	return common.SystemError(err)
 }
 
-func CreateInstanceConfigForAgent(instanceId string, configName string) error {
-	agentPipelineConfig := entity.AgentPipelineConfig{
-		AgentInstanceId:    instanceId,
-		PipelineConfigName: configName,
-	}
-	err := s.Db.FirstOrCreate(&agentPipelineConfig).Error
-	return err
-}
-
-//func CreateInstanceConfigForAgentInGroup(agentInstanceIds []string, configName string) error {
-//	agentInstanceConfigs := make([]entity.AgentInstanceConfig, 0)
-//	for _, instanceId := range agentInstanceIds {
-//		agentInstanceConfig := entity.AgentInstanceConfig{
-//			AgentInstanceId:    instanceId,
-//			InstanceConfigName: configName,
-//		}
-//		agentInstanceConfigs = append(agentInstanceConfigs, agentInstanceConfig)
-//	}
-//
-//	if len(agentInstanceConfigs) > 0 {
-//		err := s.Db.Create(agentInstanceConfigs).Error
-//		return common.SystemError(err)
-//	}
-//
-//	return nil
-//}
-
 func DeleteInstanceConfigForAgentGroup(groupName string, configName string) error {
 	removeConfig := entity.InstanceConfig{
 		Name: configName,
@@ -90,28 +77,6 @@ func DeleteInstanceConfigForAgentGroup(groupName string, configName string) erro
 	return common.SystemError(err)
 }
 
-func DeleteInstanceConfigForAgentInGroup(agentInstanceIds []string, configName string) error {
-	agentInstanceConfigs := make([]entity.AgentInstanceConfig, 0)
-	for _, instanceId := range agentInstanceIds {
-		agentInstanceConfig := entity.AgentInstanceConfig{
-			AgentInstanceId:    instanceId,
-			InstanceConfigName: configName,
-		}
-		agentInstanceConfigs = append(agentInstanceConfigs, agentInstanceConfig)
-	}
-	if len(agentInstanceConfigs) > 0 {
-		err := s.Db.Delete(agentInstanceConfigs).Error
-		return common.SystemError(err)
-	}
-	return nil
-}
-
 func DeleteAllInstanceConfigAndAgent() {
 	s.Db.Exec("TRUNCATE TABLE agent_instance_config")
 }
-
-func ListAgentInstanceConfig() []*entity.AgentInstanceConfig {
-	agentInstanceConfigs := make([]*entity.AgentInstanceConfig, 0)
-	s.Db.Find(&agentInstanceConfigs)
-	return agentInstanceConfigs
-}
diff --git a/config_server/service/repository/pipeline_config.go b/config_server/service/repository/pipeline_config.go
index a4fcd2200e..c570b0fa49 100644
--- a/config_server/service/repository/pipeline_config.go
+++ b/config_server/service/repository/pipeline_config.go
@@ -5,6 +5,20 @@ import (
 	"config-server/entity"
 )
 
+func GetPipelineConfigByNames(names ...string) ([]*entity.PipelineConfig, error) {
+	pipelineConfigs := make([]*entity.PipelineConfig, 0)
+	row := s.Db.Where("name in (?)", names).Find(&pipelineConfigs).RowsAffected
+	if row != int64(len(names)) {
+		return nil, common.ServerErrorWithMsg("pipelineNames=%s can not be found", names)
+	}
+	return pipelineConfigs, nil
+}
+
+func GetPipelineConfigsByAgent(agent *entity.Agent) error {
+	err := s.Db.Preload("Tags.PipelineConfigs").Where("instance_id=?", agent.InstanceId).Find(agent).Error
+	return common.SystemError(err)
+}
+
 func CreatePipelineConfig(config *entity.PipelineConfig) error {
 	row := s.Db.Create(config).RowsAffected
 	if row != 1 {
@@ -52,31 +66,6 @@ func CreatePipelineConfigForAgentGroup(groupName string, configName string) erro
 	return common.SystemError(err)
 }
 
-func CreatePipelineConfigForAgent(instanceId string, configName string) error {
-	agentPipelineConfig := entity.AgentPipelineConfig{
-		AgentInstanceId:    instanceId,
-		PipelineConfigName: configName,
-	}
-	err := s.Db.FirstOrCreate(&agentPipelineConfig).Error
-	return err
-}
-
-//func CreatePipelineConfigForAgentInGroup(agentInstanceIds []string, configName string) error {
-//	agentPipelineConfigs := make([]entity.AgentPipelineConfig, 0)
-//	for _, instanceId := range agentInstanceIds {
-//		agentPipelineConfig := entity.AgentPipelineConfig{
-//			AgentInstanceId:    instanceId,
-//			PipelineConfigName: configName,
-//		}
-//		agentPipelineConfigs = append(agentPipelineConfigs, agentPipelineConfig)
-//	}
-//	if len(agentPipelineConfigs) > 0 {
-//		err := s.Db.Create(&agentPipelineConfigs).Error
-//		return common.SystemError(err)
-//	}
-//	return nil
-//}
-
 func DeletePipelineConfigForAgentGroup(groupName string, configName string) error {
 	removeConfig := entity.PipelineConfig{
 		Name: configName,
@@ -88,28 +77,6 @@ func DeletePipelineConfigForAgentGroup(groupName string, configName string) erro
 	return common.SystemError(err)
 }
 
-func DeletePipelineConfigForAgentInGroup(agentInstanceIds []string, configName string) error {
-	agentPipelineConfigs := make([]entity.AgentPipelineConfig, 0)
-	for _, instanceId := range agentInstanceIds {
-		agentPipelineConfig := entity.AgentPipelineConfig{
-			AgentInstanceId:    instanceId,
-			PipelineConfigName: configName,
-		}
-		agentPipelineConfigs = append(agentPipelineConfigs, agentPipelineConfig)
-	}
-	if len(agentPipelineConfigs) > 0 {
-		err := s.Db.Delete(&agentPipelineConfigs).Error
-		return common.SystemError(err)
-	}
-	return nil
-}
-
 func DeleteAllPipelineConfigAndAgent() {
 	s.Db.Exec("TRUNCATE TABLE agent_pipeline_config")
 }
-
-func ListAgentPipelineConfig() []*entity.AgentPipelineConfig {
-	agentPipelineConfigs := make([]*entity.AgentPipelineConfig, 0)
-	s.Db.Find(&agentPipelineConfigs)
-	return agentPipelineConfigs
-}
diff --git a/config_server/service/router/router.go b/config_server/service/router/router.go
index 2d1ffec5f8..87e8d36a1f 100644
--- a/config_server/service/router/router.go
+++ b/config_server/service/router/router.go
@@ -25,7 +25,6 @@ func initUserRouter(router *gin.Engine) {
 		userRouter.POST("/ApplyPipelineConfigToAgentGroup", handler.ApplyPipelineConfigToAgentGroup)
 		userRouter.POST("/RemovePipelineConfigFromAgentGroup", handler.RemovePipelineConfigFromAgentGroup)
 		userRouter.POST("/GetAppliedAgentGroupsWithPipelineConfig", handler.GetAppliedAgentGroupsWithPipelineConfig)
-		userRouter.POST("/GetPipelineConfigStatusList", handler.GetPipelineConfigStatusList)
 
 		userRouter.POST("/CreateInstanceConfig", handler.CreateInstanceConfig)
 		userRouter.POST("/UpdateInstanceConfig", handler.UpdateInstanceConfig)
@@ -35,7 +34,6 @@ func initUserRouter(router *gin.Engine) {
 		userRouter.POST("/ApplyInstanceConfigToAgentGroup", handler.ApplyInstanceConfigToAgentGroup)
 		userRouter.POST("/RemoveInstanceConfigFromAgentGroup", handler.RemoveInstanceConfigFromAgentGroup)
 		userRouter.POST("/GetAppliedAgentGroupsWithInstanceConfig", handler.GetAppliedAgentGroupsWithInstanceConfig)
-		userRouter.POST("/GetInstanceConfigStatusList", handler.GetInstanceConfigStatusList)
 	}
 
 }
@@ -45,11 +43,9 @@ func initAgentRouter(router *gin.Engine) {
 	{
 		agentRouter.POST("/Heartbeat", handler.HeartBeat)
 		agentRouter.POST("/FetchPipelineConfig", handler.FetchPipelineConfig)
-		//agent有bug暂时不开启此路由
-		//agentRouter.POST("/FetchProcessConfig", handler.FetchProcessConfig)
+		agentRouter.POST("/FetchInstanceConfig", handler.FetchInstanceConfig)
 	}
 	handler.CheckAgentExist()
-	handler.AppliedOrRemoveConfigForAgentGroup()
 }
 
 func initTest(router *gin.Engine) {
diff --git a/config_server/service/service/agent.go b/config_server/service/service/agent.go
index d2d68d703b..7c04d6d673 100644
--- a/config_server/service/service/agent.go
+++ b/config_server/service/service/agent.go
@@ -4,7 +4,7 @@ import (
 	"config-server/common"
 	"config-server/entity"
 	"config-server/manager"
-	"config-server/manager/flag"
+	"config-server/manager/state"
 	proto "config-server/protov2"
 	"config-server/repository"
 	"config-server/utils"
@@ -36,12 +36,12 @@ func HeartBeat(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error
 	//假设数据库保存的sequenceNum=3,agent给的是10,
 	//如果在判断rationality=false立即return,数据库中保存的一直是3,agent一直重传全部状态
 	if !rationality {
-		res.Flags = res.Flags | uint64(flag.ResponseMap[flag.ReportFullState].Code)
+		res.Flags = res.Flags | uint64(state.ReportFullState.Code)
 	}
 
 	currentHeatBeatTime := time.Now().UnixNano()
+	req.Tags = manager.AddDefaultAgentGroup(req.Tags)
 	agent := entity.ParseHeartBeatRequest2BasicAgent(req, currentHeatBeatTime)
-	agent.Tags = manager.AddDefaultAgentGroup(agent.Tags)
 
 	//Regardless of whether sequenceN is legal or not, we should keep the basic information of the agent (sequenceNum, instanceId, capabilities, flags, etc.)
 	err = manager.CreateOrUpdateAgentBasicInfo(agent)
@@ -49,13 +49,13 @@ func HeartBeat(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error
 		return common.SystemError(err)
 	}
 
-	//如果req未设置fullState,agent会不会上传其他的configStatus
-	err = flag.HandleRequestFlags(req, res)
+	//如果req未设置fullState,agent不会上传configStatus
+	err = state.HandleRequestFlags(req, res)
 	if err != nil {
 		return common.SystemError(err)
 	}
 
-	err = flag.HandleResponseFlags(req, res)
+	err = state.HandleAgentCapabilities(req, res)
 	if err != nil {
 		return common.SystemError(err)
 	}
@@ -63,6 +63,8 @@ func HeartBeat(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error
 	return nil
 }
 
+// 心跳检测中的tag只是为了获取某个组的配置,而不是让某个agent加入到某个组
+
 func FetchPipelineConfigDetail(req *proto.FetchConfigRequest, res *proto.FetchConfigResponse) error {
 	instanceId := req.InstanceId
 	if instanceId == nil {
@@ -72,24 +74,23 @@ func FetchPipelineConfigDetail(req *proto.FetchConfigRequest, res *proto.FetchCo
 	var err error
 	strInstanceId := string(instanceId)
 
-	//创建或更新pipelineConfig的status and message
-	agentPipelineConfigs := make([]*entity.AgentPipelineConfig, 0)
-	for _, reqConfig := range req.ReqConfigs {
-		agentPipelineConfig := entity.ParseProtoConfigInfo2AgentPipelineConfig(strInstanceId, reqConfig)
-		agentPipelineConfigs = append(agentPipelineConfigs, agentPipelineConfig)
-	}
-
-	err = manager.CreateOrUpdateAgentPipelineConfigs(agentPipelineConfigs)
+	//需要更新配置状态
+	err = manager.SavePipelineConfigStatus(req.ReqConfigs, strInstanceId)
 	if err != nil {
 		return common.SystemError(err)
 	}
 
-	//返回pipelineConfigDetail
-	pipelineConfigUpdates, err := manager.GetPipelineConfigs(strInstanceId, true)
+	configNames := utils.Map(req.ReqConfigs, func(info *proto.ConfigInfo) string {
+		return info.Name
+	})
+	pipelineConfigUpdates, err := repository.GetPipelineConfigByNames(configNames...)
 	if err != nil {
-		return common.SystemError(err)
+		return err
 	}
-	res.ConfigDetails = pipelineConfigUpdates
+
+	res.ConfigDetails = utils.Map(pipelineConfigUpdates, func(config *entity.PipelineConfig) *proto.ConfigDetail {
+		return config.Parse2ProtoPipelineConfigDetail(true)
+	})
 	return nil
 }
 
@@ -102,23 +103,23 @@ func FetchInstanceConfigDetail(req *proto.FetchConfigRequest, res *proto.FetchCo
 	var err error
 	strInstanceId := string(instanceId)
 
-	agentInstanceConfigs := make([]*entity.AgentInstanceConfig, 0)
-	for _, reqConfig := range req.ReqConfigs {
-		agentInstanceConfig := entity.ParseProtoConfigInfo2AgentInstanceConfig(strInstanceId, reqConfig)
-		agentInstanceConfigs = append(agentInstanceConfigs, agentInstanceConfig)
-	}
-
-	err = manager.CreateOrUpdateAgentInstanceConfigs(agentInstanceConfigs)
+	//需要更新配置状态
+	err = manager.SaveInstanceConfigStatus(req.ReqConfigs, strInstanceId)
 	if err != nil {
 		return common.SystemError(err)
 	}
 
-	//获取对应的configDetails
-	instanceConfigUpdates, err := manager.GetInstanceConfigs(strInstanceId, true)
+	configNames := utils.Map(req.ReqConfigs, func(info *proto.ConfigInfo) string {
+		return info.Name
+	})
+	instanceConfigUpdates, err := repository.GetInstanceConfigByNames(configNames...)
 	if err != nil {
-		return common.SystemError(err)
+		return err
 	}
-	res.ConfigDetails = instanceConfigUpdates
+
+	res.ConfigDetails = utils.Map(instanceConfigUpdates, func(config *entity.InstanceConfig) *proto.ConfigDetail {
+		return config.Parse2ProtoInstanceConfigDetail(true)
+	})
 	return nil
 }
 
@@ -138,37 +139,3 @@ func ListAgentsInGroup(req *proto.ListAgentsRequest, res *proto.ListAgentsRespon
 	res.Agents = protoAgents
 	return nil
 }
-
-func GetPipelineConfigStatusList(req *proto.GetConfigStatusListRequest, res *proto.GetConfigStatusListResponse) error {
-	instanceId := req.InstanceId
-	if instanceId == nil {
-		return common.ValidateErrorWithMsg("required fields instanceId could not be null")
-	}
-	configs, err := repository.GetPipelineConfigStatusList(string(instanceId))
-	if err != nil {
-		return common.SystemError(err)
-	}
-	agentConfigStatusList := make([]*proto.AgentConfigStatus, 0)
-	for _, config := range configs {
-		agentConfigStatusList = append(agentConfigStatusList, config.Parse2ProtoAgentConfigStatus())
-	}
-	res.AgentConfigStatus = agentConfigStatusList
-	return nil
-}
-
-func GetInstanceConfigStatusList(req *proto.GetConfigStatusListRequest, res *proto.GetConfigStatusListResponse) error {
-	instanceId := req.InstanceId
-	if instanceId == nil {
-		return common.ValidateErrorWithMsg("required fields instanceId could not be null")
-	}
-	configs, err := repository.GetInstanceConfigStatusList(string(instanceId))
-	if err != nil {
-		return common.SystemError(err)
-	}
-	agentConfigStatusList := make([]*proto.AgentConfigStatus, 0)
-	for _, config := range configs {
-		agentConfigStatusList = append(agentConfigStatusList, config.Parse2ProtoAgentConfigStatus())
-	}
-	res.AgentConfigStatus = agentConfigStatusList
-	return nil
-}
diff --git a/config_server/service/service/agent_group.go b/config_server/service/service/agent_group.go
index ed01b45f59..5633f2bac3 100644
--- a/config_server/service/service/agent_group.go
+++ b/config_server/service/service/agent_group.go
@@ -3,25 +3,12 @@ package service
 import (
 	"config-server/common"
 	"config-server/entity"
-	"config-server/manager"
+
 	proto "config-server/protov2"
 	"config-server/repository"
 	"config-server/utils"
 )
 
-// AppliedOrRemoveConfigForAgentGroup 定期检查在group中的agent与config的关系是否符合group与config的关系
-func AppliedOrRemoveConfigForAgentGroup(timeLimit int64) {
-	utils.TimedTask(timeLimit, func(int64) {
-		agentGroupDetails, err := repository.GetAllAgentGroupDetail(true, true, true)
-		if err != nil {
-			panic(err)
-		}
-		utils.ParallelProcessTask(agentGroupDetails,
-			manager.AppliedOrRemovePipelineConfigForAgentGroup,
-			manager.AppliedOrRemoveInstanceConfigForAgentGroup)
-	})
-}
-
 func CreateAgentGroup(req *proto.CreateAgentGroupRequest, res *proto.CreateAgentGroupResponse) error {
 	agentGroup := req.AgentGroup
 	if agentGroup == nil {
diff --git a/config_server/service/service/instance_config.go b/config_server/service/service/instance_config.go
index 71e4c18d95..890a73145b 100644
--- a/config_server/service/service/instance_config.go
+++ b/config_server/service/service/instance_config.go
@@ -32,6 +32,7 @@ func UpdateInstanceConfig(req *proto.UpdateConfigRequest, res *proto.UpdateConfi
 	if configDetail.Version == 0 {
 		return common.ValidateErrorWithMsg("required field version could not be null")
 	}
+	configDetail.Version += 1
 	instanceConfig := entity.ParseProtoInstanceConfig2InstanceConfig(configDetail)
 	err := repository.UpdateInstanceConfig(instanceConfig)
 	return common.SystemError(err)
@@ -89,18 +90,6 @@ func ApplyInstanceConfigToAgentGroup(req *proto.ApplyConfigToAgentGroupRequest,
 	if err != nil {
 		return common.SystemError(err)
 	}
-
-	agents, err := repository.ListAgentsByGroupName(groupName)
-	if err != nil {
-		return common.SystemError(err)
-	}
-
-	for _, agent := range agents {
-		err := repository.CreateInstanceConfigForAgent(agent.InstanceId, configName)
-		if err != nil {
-			return err
-		}
-	}
 	return nil
 }
 
@@ -115,18 +104,7 @@ func RemoveInstanceConfigFromAgentGroup(req *proto.RemoveConfigFromAgentGroupReq
 	if err != nil {
 		return common.SystemError(err)
 	}
-
-	agents, err := repository.ListAgentsByGroupName(groupName)
-	if err != nil {
-		return common.SystemError(err)
-	}
-
-	agentInstanceIds := make([]string, 0)
-	for _, agent := range agents {
-		agentInstanceIds = append(agentInstanceIds, agent.InstanceId)
-	}
-
-	return repository.DeleteInstanceConfigForAgentInGroup(agentInstanceIds, configName)
+	return nil
 }
 
 func GetAppliedInstanceConfigsForAgentGroup(req *proto.GetAppliedConfigsForAgentGroupRequest, res *proto.GetAppliedConfigsForAgentGroupResponse) error {
diff --git a/config_server/service/service/pipeline_config.go b/config_server/service/service/pipeline_config.go
index 3e7a8e2d72..52bb5b3dc1 100644
--- a/config_server/service/service/pipeline_config.go
+++ b/config_server/service/service/pipeline_config.go
@@ -24,6 +24,8 @@ func CreatePipelineConfig(req *proto.CreateConfigRequest, res *proto.CreateConfi
 
 }
 
+//更新配置的时候version也要更新
+
 func UpdatePipelineConfig(req *proto.UpdateConfigRequest, res *proto.UpdateConfigResponse) error {
 	configDetail := req.ConfigDetail
 	if configDetail.Name == "" {
@@ -33,6 +35,7 @@ func UpdatePipelineConfig(req *proto.UpdateConfigRequest, res *proto.UpdateConfi
 	if configDetail.Version == 0 {
 		return common.ValidateErrorWithMsg("required field version could not be null")
 	}
+	configDetail.Version += 1
 	pipelineConfig := entity.ParseProtoPipelineConfig2PipelineConfig(configDetail)
 	err := repository.UpdatePipelineConfig(pipelineConfig)
 	return common.SystemError(err)
@@ -91,17 +94,6 @@ func ApplyPipelineConfigToAgentGroup(req *proto.ApplyConfigToAgentGroupRequest,
 		return common.SystemError(err)
 	}
 
-	agents, err := repository.ListAgentsByGroupName(groupName)
-	if err != nil {
-		return common.SystemError(err)
-	}
-
-	for _, agent := range agents {
-		err := repository.CreatePipelineConfigForAgent(agent.InstanceId, configName)
-		if err != nil {
-			return err
-		}
-	}
 	return nil
 }
 
@@ -111,26 +103,12 @@ func RemovePipelineConfigFromAgentGroup(req *proto.RemoveConfigFromAgentGroupReq
 		return common.ValidateErrorWithMsg("required fields groupName could not be null")
 	}
 	configName := req.ConfigName
-	if configName == "" {
-		return common.ValidateErrorWithMsg("required fields configName could not be null")
-	}
 
 	err := repository.DeletePipelineConfigForAgentGroup(groupName, configName)
 	if err != nil {
 		return common.SystemError(err)
 	}
-
-	agents, err := repository.ListAgentsByGroupName(groupName)
-	if err != nil {
-		return common.SystemError(err)
-	}
-
-	agentInstanceIds := make([]string, 0)
-	for _, agent := range agents {
-		agentInstanceIds = append(agentInstanceIds, agent.InstanceId)
-	}
-
-	return repository.DeletePipelineConfigForAgentInGroup(agentInstanceIds, configName)
+	return nil
 }
 
 func GetAppliedPipelineConfigsForAgentGroup(req *proto.GetAppliedConfigsForAgentGroupRequest, res *proto.GetAppliedConfigsForAgentGroupResponse) error {
diff --git a/config_server/service/store/gorm.go b/config_server/service/store/gorm.go
index ec8b2555e1..0eaf96e0ba 100644
--- a/config_server/service/store/gorm.go
+++ b/config_server/service/store/gorm.go
@@ -20,8 +20,6 @@ var tableList = []any{
 	&entity.PipelineConfig{},
 	&entity.AgentGroup{},
 	&entity.Agent{},
-	&entity.AgentPipelineConfig{},
-	&entity.AgentInstanceConfig{},
 }
 
 var tableNameList = []string{
@@ -35,8 +33,6 @@ var tableNameList = []string{
 
 	entity.InstanceConfig{}.TableName(),
 	entity.PipelineConfig{}.TableName(),
-	entity.AgentPipelineConfig{}.TableName(),
-	entity.AgentInstanceConfig{}.TableName(),
 }
 
 func (s *GormStore) Connect2Db() error {
diff --git a/config_server/service/test/common_test.go b/config_server/service/test/common_test.go
new file mode 100644
index 0000000000..2b6b041c6b
--- /dev/null
+++ b/config_server/service/test/common_test.go
@@ -0,0 +1,20 @@
+package test
+
+import (
+	"config-server/protov2"
+	"fmt"
+	"google.golang.org/protobuf/proto"
+	"reflect"
+	"testing"
+)
+
+func NewObj[T proto.Message]() {
+	var ptr T
+	fmt.Println(reflect.TypeOf(ptr))
+	fmt.Println(reflect.New(reflect.TypeOf(ptr)).Interface())
+}
+
+func TestProto(t *testing.T) {
+	//NewObj[protov2.CreateAgentGroupRequest]()
+	NewObj[*protov2.CreateAgentGroupRequest]()
+}
diff --git a/config_server/service/utils/environment.go b/config_server/service/utils/environment.go
index e0a0e50d09..72bbc4ac3a 100644
--- a/config_server/service/utils/environment.go
+++ b/config_server/service/utils/environment.go
@@ -2,28 +2,14 @@ package utils
 
 import (
 	"log"
-	"path/filepath"
+	"os"
 )
 
-func GetEnvConfig(path string) (map[string]any, error) {
-	envMap := make(map[string]any)
-	err := ReadJson(path, &envMap)
-	if err != nil {
-		return nil, err
-	}
-	return envMap, err
-}
-
 func GetEnvName() (string, error) {
-	path, err := filepath.Abs("cmd/env.json")
-	if err != nil {
-		panic("can not find env file, it should be placed in cmd/env.json")
-	}
-	config, err := GetEnvConfig(path)
-	if err != nil {
-		return "", err
+	name := os.Getenv("GO_ENV")
+	if name == "" {
+		name = "dev"
 	}
-	name := config["env"].(string)
 	log.Printf("the environment is %s", name)
 	return name, nil
 }
diff --git a/config_server/service/utils/list.go b/config_server/service/utils/list.go
index ff920e5c1b..f0e269c81d 100644
--- a/config_server/service/utils/list.go
+++ b/config_server/service/utils/list.go
@@ -1,11 +1,11 @@
 package utils
 
-func ContainElement[T comparable](arr []T, val any, eqCondition func(T, any) bool) bool {
+func ContainElement[T, E comparable](arr []T, val E, eqCondition func(T, E) bool) bool {
 	if arr == nil || len(arr) == 0 {
 		return false
 	}
 	for _, element := range arr {
-		if element == val || eqCondition != nil && eqCondition(element, val) {
+		if eqCondition != nil && eqCondition(element, val) {
 			return true
 		}
 	}
@@ -38,3 +38,21 @@ func ReplaceElement[T comparable](arr []T, val T, eqCondition func(T, any) bool)
 		}
 	}
 }
+
+func Filter[T comparable](arr []T, fn func(T) bool) []T {
+	finalArr := make([]T, 0)
+	for _, element := range arr {
+		if fn(element) {
+			finalArr = append(finalArr, element)
+		}
+	}
+	return finalArr
+}
+
+func Map[T, E any](arr []T, fn func(T) E) []E {
+	finalArr := make([]E, 0)
+	for _, element := range arr {
+		finalArr = append(finalArr, fn(element))
+	}
+	return finalArr
+}

From 7d11b8dc7afd5afe6975974851a826f49b3e60be Mon Sep 17 00:00:00 2001
From: ww67652 <1749113286@qq.com>
Date: Sun, 27 Oct 2024 17:37:17 +0800
Subject: [PATCH 05/11] feat: support for agent hostid and Join the default
 group upon backend startup

---
 config_server/service/entity/agent.go     |   3 +
 config_server/service/protov2/agent.pb.go | 294 +++++++++++-----------
 config_server/service/service/agent.go    |  27 ++
 config_server/service/store/gorm.go       |   4 +-
 4 files changed, 184 insertions(+), 144 deletions(-)

diff --git a/config_server/service/entity/agent.go b/config_server/service/entity/agent.go
index 5707bb5b98..88c92e6459 100644
--- a/config_server/service/entity/agent.go
+++ b/config_server/service/entity/agent.go
@@ -11,6 +11,7 @@ type AgentAttributes struct {
 	Version  []byte
 	Ip       []byte
 	Hostname []byte
+	Hostid   []byte
 	Extras   map[string][]byte
 }
 
@@ -19,6 +20,7 @@ func (a *AgentAttributes) Parse2Proto() *proto.AgentAttributes {
 	protoAgentAttributes.Version = a.Version
 	protoAgentAttributes.Ip = a.Ip
 	protoAgentAttributes.Hostname = a.Hostname
+	protoAgentAttributes.Hostid = a.Hostid
 	protoAgentAttributes.Extras = a.Extras
 	return protoAgentAttributes
 }
@@ -28,6 +30,7 @@ func ParseProtoAgentAttributes2AgentAttributes(attributes *proto.AgentAttributes
 	agentAttributes.Version = attributes.Version
 	agentAttributes.Ip = attributes.Ip
 	agentAttributes.Hostname = attributes.Hostname
+	agentAttributes.Hostid = attributes.Hostid
 	agentAttributes.Extras = attributes.Extras
 	return agentAttributes
 }
diff --git a/config_server/service/protov2/agent.pb.go b/config_server/service/protov2/agent.pb.go
index 9911dd26fc..5f7e5e41f6 100644
--- a/config_server/service/protov2/agent.pb.go
+++ b/config_server/service/protov2/agent.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.35.1
-// 	protoc        v3.5.0
+// 	protoc        v3.20.0
 // source: agent.proto
 
 package protov2
@@ -498,6 +498,7 @@ type AgentAttributes struct {
 	Version  []byte            `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`                                                                                         // Agent's version
 	Ip       []byte            `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"`                                                                                                   // Agent's ip
 	Hostname []byte            `protobuf:"bytes,3,opt,name=hostname,proto3" json:"hostname,omitempty"`                                                                                       // Agent's hostname
+	Hostid   []byte            `protobuf:"bytes,4,opt,name=hostid,proto3" json:"hostid,omitempty"`                                                                                           // Agent's hostid  https://opentelemetry.io/docs/specs/semconv/attributes-registry/host/
 	Extras   map[string][]byte `protobuf:"bytes,100,rep,name=extras,proto3" json:"extras,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Agent's other attributes
 }
 
@@ -552,6 +553,13 @@ func (x *AgentAttributes) GetHostname() []byte {
 	return nil
 }
 
+func (x *AgentAttributes) GetHostid() []byte {
+	if x != nil {
+		return x.Hostid
+	}
+	return nil
+}
+
 func (x *AgentAttributes) GetExtras() map[string][]byte {
 	if x != nil {
 		return x.Extras
@@ -1143,153 +1151,155 @@ var file_agent_proto_rawDesc = []byte{
 	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x43,
 	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61,
 	0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xc8, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xe0, 0x01,
 	0x0a, 0x0f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
 	0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
 	0x28, 0x0c, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69,
 	0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x68,
 	0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x68,
-	0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x65, 0x78, 0x74, 0x72, 0x61,
-	0x73, 0x18, 0x64, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41,
-	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x73,
-	0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x65, 0x78, 0x74, 0x72, 0x61, 0x73, 0x1a, 0x39, 0x0a,
-	0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
-	0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14,
-	0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76,
-	0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xad, 0x04, 0x0a, 0x10, 0x48, 0x65, 0x61,
-	0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
-	0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c,
-	0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x04, 0x52, 0x0b, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x4e, 0x75, 0x6d, 0x12,
-	0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
-	0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
-	0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
-	0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79,
-	0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x54,
-	0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
-	0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41,
-	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69,
-	0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
-	0x54, 0x61, 0x67, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x75, 0x6e,
-	0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0d, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
-	0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65,
-	0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x54,
-	0x69, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x10, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f,
-	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e,
-	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x70, 0x69, 0x70, 0x65,
-	0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x36, 0x0a, 0x10, 0x69,
-	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18,
-	0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e,
-	0x66, 0x6f, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6f,
-	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x43,
-	0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74,
-	0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c,
-	0x61, 0x67, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73,
-	0x12, 0x16, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c,
-	0x52, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x22, 0x54, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07,
-	0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76,
-	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c,
-	0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x70,
-	0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12,
-	0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74,
-	0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69,
-	0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12,
-	0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04,
-	0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65,
-	0x22, 0x92, 0x03, 0x0a, 0x11, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f,
-	0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f,
-	0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52,
-	0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
-	0x69, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x17, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f,
-	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x04,
-	0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74,
-	0x61, 0x69, 0x6c, 0x52, 0x15, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x17, 0x69, 0x6e,
-	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x70,
-	0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x15, 0x69, 0x6e, 0x73, 0x74,
-	0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
-	0x73, 0x12, 0x44, 0x0a, 0x16, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
-	0x61, 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61, 0x69,
-	0x6c, 0x52, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
-	0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73,
-	0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x16, 0x0a,
-	0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f,
-	0x70, 0x61, 0x71, 0x75, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x12, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
-	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x69,
-	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
-	0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x0b,
-	0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x0b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a,
-	0x72, 0x65, 0x71, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x13, 0x46,
-	0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
-	0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0e, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20,
+	0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x69,
+	0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x69, 0x64, 0x12,
+	0x34, 0x0a, 0x06, 0x65, 0x78, 0x74, 0x72, 0x61, 0x73, 0x18, 0x64, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x1c, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+	0x73, 0x2e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x65,
+	0x78, 0x74, 0x72, 0x61, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x73, 0x45,
+	0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
+	0x22, 0xad, 0x04, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65,
+	0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x65, 0x71, 0x75,
+	0x65, 0x6e, 0x63, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62,
+	0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63,
+	0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69,
+	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c,
+	0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a,
+	0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x0a, 0x61,
+	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x10, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+	0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x22, 0x0a,
+	0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67,
+	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52, 0x04, 0x74, 0x61, 0x67,
+	0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x75, 0x6e, 0x6e, 0x69,
+	0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x72,
+	0x74, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b,
+	0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x10, 0x70,
+	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18,
+	0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e,
+	0x66, 0x6f, 0x52, 0x0f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x73, 0x12, 0x36, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74,
+	0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x63,
+	0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x0c,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x6e,
+	0x66, 0x6f, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+	0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28,
+	0x04, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71,
+	0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65,
+	0x22, 0x54, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
+	0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+	0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16,
+	0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06,
+	0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x70, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+	0x64, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+	0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52,
+	0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72,
+	0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x65, 0x78,
+	0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x92, 0x03, 0x0a, 0x11, 0x48, 0x65, 0x61,
+	0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d,
+	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a,
+	0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62,
+	0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63,
+	0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x17, 0x70,
+	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75,
+	0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x15, 0x70, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74,
+	0x65, 0x73, 0x12, 0x45, 0x0a, 0x17, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20,
 	0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
-	0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
-	0x73, 0x22, 0x4d, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x65,
-	0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x0c, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x2a, 0x40, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
-	0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x41,
-	0x50, 0x50, 0x4c, 0x59, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x50, 0x50,
-	0x4c, 0x49, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44,
-	0x10, 0x03, 0x2a, 0x83, 0x01, 0x0a, 0x11, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61,
-	0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x1a, 0x55, 0x6e, 0x73, 0x70,
-	0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61,
-	0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65,
-	0x70, 0x74, 0x73, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x49, 0x6e,
-	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x10, 0x02, 0x12, 0x18,
-	0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43,
-	0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x04, 0x2a, 0x3a, 0x0a, 0x0c, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66,
-	0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61,
-	0x74, 0x65, 0x10, 0x01, 0x2a, 0xad, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43,
-	0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x55,
-	0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
-	0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10,
-	0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
-	0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x69, 0x70,
-	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75,
-	0x73, 0x10, 0x02, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x49, 0x6e,
-	0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x43,
-	0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x10, 0x08, 0x2a, 0x80, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,
-	0x65, 0x64, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x75,
-	0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x65, 0x74,
-	0x63, 0x68, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x65, 0x74, 0x63,
-	0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44,
-	0x65, 0x74, 0x61, 0x69, 0x6c, 0x10, 0x04, 0x42, 0x0b, 0x5a, 0x09, 0x2f, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x76, 0x32, 0x3b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x69, 0x6c, 0x52, 0x15, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x16, 0x63, 0x75, 0x73,
+	0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61,
+	0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
+	0x61, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f,
+	0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12,
+	0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05,
+	0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18,
+	0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x22, 0x82, 0x01,
+	0x0a, 0x12, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
+	0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+	0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x0b, 0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x72, 0x65, 0x71, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x13, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65,
+	0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x4d, 0x0a, 0x0e, 0x43, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f,
+	0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2a, 0x40, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45,
+	0x54, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x50, 0x50, 0x4c, 0x59, 0x49, 0x4e, 0x47, 0x10,
+	0x01, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a,
+	0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x83, 0x01, 0x0a, 0x11, 0x41,
+	0x67, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73,
+	0x12, 0x1e, 0x0a, 0x1a, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x41,
+	0x67, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x10, 0x00,
+	0x12, 0x19, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x50, 0x69, 0x70, 0x65, 0x6c,
+	0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x41,
+	0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74,
+	0x73, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x04,
+	0x2a, 0x3a, 0x0a, 0x0c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73,
+	0x12, 0x1b, 0x0a, 0x17, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73,
+	0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0d, 0x0a,
+	0x09, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10, 0x01, 0x2a, 0xad, 0x01, 0x0a,
+	0x12, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
+	0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,
+	0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69,
+	0x74, 0x79, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x41,
+	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x65,
+	0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x10, 0x02, 0x12, 0x1f, 0x0a, 0x1b, 0x52,
+	0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a,
+	0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d,
+	0x6d, 0x61, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x10, 0x08, 0x2a, 0x80, 0x01, 0x0a,
+	0x0d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1c,
+	0x0a, 0x18, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x55,
+	0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f,
+	0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10,
+	0x01, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x65, 0x74, 0x63, 0x68, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69,
+	0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x10, 0x02,
+	0x12, 0x1d, 0x0a, 0x19, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
+	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x10, 0x04, 0x42,
+	0x0b, 0x5a, 0x09, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x76, 0x32, 0x3b, 0x62, 0x06, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
diff --git a/config_server/service/service/agent.go b/config_server/service/service/agent.go
index 7c04d6d673..48e8712334 100644
--- a/config_server/service/service/agent.go
+++ b/config_server/service/service/agent.go
@@ -22,6 +22,30 @@ func CheckAgentExist(timeLimit int64) {
 	})
 }
 
+func createDefaultGroupWhenStart() {
+	group := &entity.AgentGroup{
+		Name:  entity.AgentGroupDefaultValue,
+		Value: entity.AgentGroupDefaultValue,
+	}
+	var err error
+	_, err = repository.GetAgentGroupDetail(entity.AgentGroupDefaultValue, false, false)
+	if err == nil {
+		// Default agent group exists
+		return
+	}
+	err = repository.CreateAgentGroup(group)
+	if err != nil {
+		panic("init default group failed...")
+	}
+}
+
+func init() {
+	createDefaultGroupWhenStart()
+}
+
+// 业务逻辑链 service/agent => {manager/state/*、manager/agent、manager/pipeline_config、manager/instance_config}
+//=>{repository/agent、repository/pipeline_config、repository/instance_config}
+
 func HeartBeat(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
 	instanceId := req.InstanceId
 	if instanceId == nil {
@@ -64,6 +88,7 @@ func HeartBeat(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error
 }
 
 // 心跳检测中的tag只是为了获取某个组的配置,而不是让某个agent加入到某个组
+//业务逻辑链 service/agent=>{manager/pipeline_config}=>{repository/agent、repository/pipeline_config}
 
 func FetchPipelineConfigDetail(req *proto.FetchConfigRequest, res *proto.FetchConfigResponse) error {
 	instanceId := req.InstanceId
@@ -94,6 +119,8 @@ func FetchPipelineConfigDetail(req *proto.FetchConfigRequest, res *proto.FetchCo
 	return nil
 }
 
+//业务逻辑链 service/agent=>{manager/instance_config}=>{repository/agent、repository/instance_config}
+
 func FetchInstanceConfigDetail(req *proto.FetchConfigRequest, res *proto.FetchConfigResponse) error {
 	instanceId := req.InstanceId
 	if instanceId == nil {
diff --git a/config_server/service/store/gorm.go b/config_server/service/store/gorm.go
index 0eaf96e0ba..ae731733b5 100644
--- a/config_server/service/store/gorm.go
+++ b/config_server/service/store/gorm.go
@@ -49,12 +49,12 @@ func (s *GormStore) Connect2Db() error {
 		return err
 	}
 	dbName := s.Config.DbName
-	log.Printf("create database %s ...", dbName)
+	log.Printf("create or connect database %s ...", dbName)
 	err = s.Db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", dbName)).Error
 	if err != nil {
 		return err
 	}
-	log.Printf("create database %s success ...", dbName)
+	log.Printf("create or connect database %s success ...", dbName)
 	log.Printf("check %s ...", dbName)
 	err = s.Db.Exec(fmt.Sprintf("USE %s", s.Config.DbName)).Error
 	if err != nil {

From d87eed989c2f8556525ca4ce417acb8cae2b2593 Mon Sep 17 00:00:00 2001
From: ww67652 <1749113286@qq.com>
Date: Mon, 28 Oct 2024 11:18:55 +0800
Subject: [PATCH 06/11] feat: Adapted to v1's HTTP status, added two APIs for
 querying config status on the user side

---
 config_server/service/common/api_error.go     |  51 +-
 config_server/service/common/http_status.go   |  37 +-
 config_server/service/common/result.go        |   6 +-
 config_server/service/config/gorm.go          |   2 +-
 config_server/service/entity/agent.go         |   4 +-
 config_server/service/handler/common.go       |   2 +-
 .../service/handler/instance_config.go        |   1 +
 .../service/handler/pipeline_config.go        |   1 +
 config_server/service/manager/agent.go        |   7 +-
 config_server/service/protov2/user.pb.go      | 882 ++++++++----------
 config_server/service/repository/agent.go     |  19 +-
 .../service/repository/agent_group.go         |  10 +-
 config_server/service/repository/base.go      |   2 +-
 .../service/repository/instance_config.go     |   8 +-
 .../service/repository/pipeline_config.go     |   8 +-
 config_server/service/router/router.go        |   2 +
 config_server/service/service/agent.go        |   5 +-
 config_server/service/service/agent_group.go  |   3 +-
 .../service/service/instance_config.go        |  13 +
 .../service/service/pipeline_config.go        |  13 +
 20 files changed, 515 insertions(+), 561 deletions(-)

diff --git a/config_server/service/common/api_error.go b/config_server/service/common/api_error.go
index b6b69244e0..4e25525871 100644
--- a/config_server/service/common/api_error.go
+++ b/config_server/service/common/api_error.go
@@ -6,40 +6,54 @@ import (
 )
 
 type ApiError struct {
-	Code    int
+	Status  HttpStatus
 	Message string
 }
 
 func (apiError ApiError) Error() string {
-	return fmt.Sprintf("Code:%d,Messgae:%s", apiError.Code, apiError.Message)
+	return fmt.Sprintf("Code:%d,Messgae:%s", apiError.Status.Code, apiError.Message)
 }
 
-func ErrorWithMsg(code int, msg string) *ApiError {
+func ErrorWithMsg(status HttpStatus, msg string) *ApiError {
 	var apiErrorResult = ApiError{
-		Code:    Failed.Code,
-		Message: Failed.Message,
+		Status:  ServerBusy,
+		Message: ServerBusy.Message,
 	}
-	if code != 0 {
-		apiErrorResult.Code = code
+	if status.Code != 0 {
+		apiErrorResult.Status = status
 	}
 	if msg != "" {
 		apiErrorResult.Message = msg
 	}
-	PrintLog(apiErrorResult.Code, apiErrorResult.Message, 3)
+	PrintLog(apiErrorResult.Status.Code, apiErrorResult.Message, 3)
 	return &apiErrorResult
 }
 
-func ServerErrorWithMsg(msg string, a ...any) *ApiError {
+//-----Server-----
+// include config、agent、agent_group already exists or not exists
+
+func ServerErrorWithMsg(status HttpStatus, msg string, a ...any) *ApiError {
 	if a == nil || len(a) == 0 {
-		return ErrorWithMsg(Failed.Code, msg)
+		return ErrorWithMsg(status, msg)
 	}
-	return ErrorWithMsg(Failed.Code, fmt.Sprintf(msg, a...))
+	return ErrorWithMsg(status, fmt.Sprintf(msg, a...))
 }
 
-func ServerError() *ApiError {
-	return ErrorWithMsg(Failed.Code, Failed.Message)
+func ServerError(msg string, a ...any) *ApiError {
+	return ServerErrorWithMsg(ServerBusy, msg, a...)
 }
 
+//-----InvalidParameter-----
+
+func ValidateErrorWithMsg(msg string) *ApiError {
+	return ErrorWithMsg(InvalidParameter, msg)
+}
+
+func ValidateError() *ApiError {
+	return ErrorWithMsg(InvalidParameter, InvalidParameter.Message)
+}
+
+//包裹异常,并用来输出堆栈日志
 //这里切记不要返回APIError,否则会出现问题(因为(ApiError)(nil)!=nil)
 
 func SystemError(err error) error {
@@ -49,15 +63,8 @@ func SystemError(err error) error {
 
 	var apiError *ApiError
 	if errors.As(err, &apiError) {
-		return ErrorWithMsg(apiError.Code, apiError.Message)
+		return ErrorWithMsg(apiError.Status, apiError.Message)
 	}
-	return ErrorWithMsg(SystemFailed.Code, err.Error())
-}
-
-func ValidateErrorWithMsg(msg string) *ApiError {
-	return ErrorWithMsg(ValidateFailed.Code, msg)
-}
 
-func ValidateError() *ApiError {
-	return ErrorWithMsg(ValidateFailed.Code, ValidateFailed.Message)
+	return ErrorWithMsg(ServerBusy, err.Error())
 }
diff --git a/config_server/service/common/http_status.go b/config_server/service/common/http_status.go
index 4226b310e8..2d11c53316 100644
--- a/config_server/service/common/http_status.go
+++ b/config_server/service/common/http_status.go
@@ -1,6 +1,7 @@
 package common
 
 import (
+	"errors"
 	"github.com/gin-gonic/gin"
 )
 
@@ -10,16 +11,40 @@ type HttpStatus struct {
 }
 
 var (
-	Success        = HttpStatus{Code: 200, Message: "success"}
-	Failed         = HttpStatus{Code: 500, Message: "failed"}
-	SystemFailed   = HttpStatus{Code: 505, Message: "systemFailed"}
-	ValidateFailed = HttpStatus{Code: 404, Message: "parameter is not"}
+	Accept     = HttpStatus{200, "Accept"}
+	BadRequest = HttpStatus{400, "BadRequest"}
+
+	AgentAlreadyExist = HttpStatus{400, "AgentAlreadyExist"}
+	AgentNotExist     = HttpStatus{404, "AgentNotExist"}
+
+	ConfigAlreadyExist = HttpStatus{400, "ConfigAlreadyExist"}
+	ConfigNotExist     = HttpStatus{404, "ConfigNotExist"}
+
+	AgentGroupAlreadyExist = HttpStatus{400, "AgentGroupAlreadyExist"}
+	AgentGroupNotExist     = HttpStatus{404, "AgentGroupNotExist"}
+
+	InvalidParameter = HttpStatus{400, "InvalidParameter"}
+	RequestTimeout   = HttpStatus{500, "RequestTimeout"}
+	ServerBusy       = HttpStatus{503, "ServerBusy"}
 )
 
 func ErrorProtobufRes(c *gin.Context, res any, err error) {
-	c.ProtoBuf(Success.Code, res)
+	c.ProtoBuf(ServerBusy.Code, res)
 }
 
 func SuccessProtobufRes(c *gin.Context, res any) {
-	c.ProtoBuf(Success.Code, res)
+	c.ProtoBuf(Accept.Code, res)
+}
+
+func ProtobufRes(c *gin.Context, err error, res any) {
+	var apiError *ApiError
+	if err == nil {
+		c.ProtoBuf(Accept.Code, res)
+		return
+	}
+	if errors.As(err, &apiError) {
+		c.ProtoBuf(apiError.Status.Code, res)
+		return
+	}
+	c.ProtoBuf(ServerBusy.Code, res)
 }
diff --git a/config_server/service/common/result.go b/config_server/service/common/result.go
index 3ad4666ad2..4d2b5c66ba 100644
--- a/config_server/service/common/result.go
+++ b/config_server/service/common/result.go
@@ -15,12 +15,12 @@ func GenerateCommonResponse(err error) *proto.CommonResponse {
 	}
 	if errors.As(err, &apiError) {
 		return &proto.CommonResponse{
-			Status:       int32(apiError.Code),
-			ErrorMessage: []byte(apiError.Message),
+			Status:       int32(apiError.Status.Code),
+			ErrorMessage: []byte(apiError.Status.Message),
 		}
 	}
 	return &proto.CommonResponse{
-		Status:       int32(Failed.Code),
+		Status:       int32(ServerBusy.Code),
 		ErrorMessage: []byte(err.Error()),
 	}
 }
diff --git a/config_server/service/config/gorm.go b/config_server/service/config/gorm.go
index dc6d454e55..3815622f3d 100644
--- a/config_server/service/config/gorm.go
+++ b/config_server/service/config/gorm.go
@@ -71,7 +71,7 @@ func getConnection(dsn string) (*GormConfig, gorm.Dialector, error) {
 	if dialect, ok := gormDialectMap[config.Type]; ok {
 		gormDialect := dialect(dsn)
 		if gormDialect == nil {
-			return nil, nil, common.ServerErrorWithMsg("connect %s:%s dbName:%s failed",
+			return nil, nil, common.ServerError("connect %s:%s dbName:%s failed",
 				config.Host, config.Port, config.DbName)
 		}
 		return config, dialect(dsn), nil
diff --git a/config_server/service/entity/agent.go b/config_server/service/entity/agent.go
index 88c92e6459..49ccd27742 100644
--- a/config_server/service/entity/agent.go
+++ b/config_server/service/entity/agent.go
@@ -83,8 +83,8 @@ func (a Agent) Parse2Proto() *proto.Agent {
 	protoAgent.Attributes = a.Attributes.Parse2Proto()
 	protoAgent.RunningStatus = a.RunningStatus
 	protoAgent.StartupTime = a.StartupTime
-	protoAgent.PipelineConfigs = a.PipelineConfigStatuses.Parse2ProtoConfigStatus()
-	protoAgent.InstanceConfigs = a.InstanceConfigStatuses.Parse2ProtoConfigStatus()
+	//protoAgent.PipelineConfigs = a.PipelineConfigStatuses.Parse2ProtoConfigStatus()
+	//protoAgent.InstanceConfigs = a.InstanceConfigStatuses.Parse2ProtoConfigStatus()
 	return protoAgent
 }
 
diff --git a/config_server/service/handler/common.go b/config_server/service/handler/common.go
index c19ccce468..e171570dd4 100644
--- a/config_server/service/handler/common.go
+++ b/config_server/service/handler/common.go
@@ -20,7 +20,7 @@ func ProtobufHandler[T any, R any](handler ProtobufFunc[T, R]) gin.HandlerFunc {
 		defer func() {
 			responseCommon := common.GenerateCommonResponse(err)
 			reflect.ValueOf(response).Elem().FieldByName("CommonResponse").Set(reflect.ValueOf(responseCommon))
-			common.SuccessProtobufRes(c, response)
+			common.ProtobufRes(c, err, response)
 		}()
 		err = c.ShouldBindBodyWith(request, binding.ProtoBuf)
 
diff --git a/config_server/service/handler/instance_config.go b/config_server/service/handler/instance_config.go
index 73009dfa6f..7d6fc784e3 100644
--- a/config_server/service/handler/instance_config.go
+++ b/config_server/service/handler/instance_config.go
@@ -13,4 +13,5 @@ var (
 	ApplyInstanceConfigToAgentGroup         = ProtobufHandler(service.ApplyInstanceConfigToAgentGroup)
 	RemoveInstanceConfigFromAgentGroup      = ProtobufHandler(service.RemoveInstanceConfigFromAgentGroup)
 	GetAppliedAgentGroupsWithInstanceConfig = ProtobufHandler(service.GetAppliedAgentGroupsForInstanceConfigName)
+	GetInstanceConfigStatusList             = ProtobufHandler(service.GetInstanceConfigStatusList)
 )
diff --git a/config_server/service/handler/pipeline_config.go b/config_server/service/handler/pipeline_config.go
index 25d16cdf38..e922613421 100644
--- a/config_server/service/handler/pipeline_config.go
+++ b/config_server/service/handler/pipeline_config.go
@@ -13,4 +13,5 @@ var (
 	ApplyPipelineConfigToAgentGroup         = ProtobufHandler(service.ApplyPipelineConfigToAgentGroup)
 	RemovePipelineConfigFromAgentGroup      = ProtobufHandler(service.RemovePipelineConfigFromAgentGroup)
 	GetAppliedAgentGroupsWithPipelineConfig = ProtobufHandler(service.GetAppliedAgentGroupsForPipelineConfigName)
+	GetPipelineConfigStatusList             = ProtobufHandler(service.GetPipelineConfigStatusList)
 )
diff --git a/config_server/service/manager/agent.go b/config_server/service/manager/agent.go
index 36bc5bbdbf..92cd111c3a 100644
--- a/config_server/service/manager/agent.go
+++ b/config_server/service/manager/agent.go
@@ -7,12 +7,11 @@ import (
 	"time"
 )
 
-func JudgeSequenceNumRationality(instanceId []byte, sequenceNum uint64) bool {
+func JudgeSequenceNumRationality(instanceId string, sequenceNum uint64) bool {
 	//最开始的心跳检测sequenceNum=0,所以sequenceNum=0是合法的
-	var strInstanceId = string(instanceId)
-	agent := repository.GetAgentByiId(strInstanceId)
+	agent, err := repository.GetAgentByID(instanceId)
 	//找不到数据的时候,同样说明是最开始的状态,应返回true
-	if agent == nil {
+	if err != nil {
 		return true
 	}
 	if sequenceNum != agent.SequenceNum+1 {
diff --git a/config_server/service/protov2/user.pb.go b/config_server/service/protov2/user.pb.go
index 89fd597edc..f560bfa0bc 100644
--- a/config_server/service/protov2/user.pb.go
+++ b/config_server/service/protov2/user.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.35.1
-// 	protoc        v3.5.0
+// 	protoc        v3.20.0
 // source: user.proto
 
 package protov2
@@ -25,15 +25,12 @@ type Agent struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Capabilities    uint64           `protobuf:"varint,1,opt,name=capabilities,proto3" json:"capabilities,omitempty"`                             // Bitmask of flags defined by AgentCapabilities enum
-	InstanceId      []byte           `protobuf:"bytes,2,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"`                // Required, Agent's unique identification, consistent throughout the process lifecycle
-	AgentType       string           `protobuf:"bytes,3,opt,name=agent_type,json=agentType,proto3" json:"agent_type,omitempty"`                   // Required, Agent's type(ilogtail, ..)
-	Attributes      *AgentAttributes `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"`                                  // Agent's basic attributes
-	RunningStatus   string           `protobuf:"bytes,5,opt,name=running_status,json=runningStatus,proto3" json:"running_status,omitempty"`       // Human readable running status
-	StartupTime     int64            `protobuf:"varint,6,opt,name=startup_time,json=startupTime,proto3" json:"startup_time,omitempty"`            // Required, Agent's startup time
-	PipelineConfigs []*ConfigInfo    `protobuf:"bytes,7,rep,name=pipeline_configs,json=pipelineConfigs,proto3" json:"pipeline_configs,omitempty"` // Information about the current PIPELINE_CONFIG held by the Agent
-	InstanceConfigs []*ConfigInfo    `protobuf:"bytes,8,rep,name=instance_configs,json=instanceConfigs,proto3" json:"instance_configs,omitempty"` // Information about the current AGENT_CONFIG held by the Agent
-	CustomCommands  []*CommandInfo   `protobuf:"bytes,9,rep,name=custom_commands,json=customCommands,proto3" json:"custom_commands,omitempty"`    // Information about command history
+	Capabilities  uint64           `protobuf:"varint,1,opt,name=capabilities,proto3" json:"capabilities,omitempty"`                       // Bitmask of flags defined by AgentCapabilities enum
+	InstanceId    []byte           `protobuf:"bytes,2,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"`          // Required, Agent's unique identification, consistent throughout the process lifecycle
+	AgentType     string           `protobuf:"bytes,3,opt,name=agent_type,json=agentType,proto3" json:"agent_type,omitempty"`             // Required, Agent's type(ilogtail, ..)
+	Attributes    *AgentAttributes `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"`                            // Agent's basic attributes
+	RunningStatus string           `protobuf:"bytes,5,opt,name=running_status,json=runningStatus,proto3" json:"running_status,omitempty"` // Human readable running status
+	StartupTime   int64            `protobuf:"varint,6,opt,name=startup_time,json=startupTime,proto3" json:"startup_time,omitempty"`      // Required, Agent's startup time
 }
 
 func (x *Agent) Reset() {
@@ -108,88 +105,6 @@ func (x *Agent) GetStartupTime() int64 {
 	return 0
 }
 
-func (x *Agent) GetPipelineConfigs() []*ConfigInfo {
-	if x != nil {
-		return x.PipelineConfigs
-	}
-	return nil
-}
-
-func (x *Agent) GetInstanceConfigs() []*ConfigInfo {
-	if x != nil {
-		return x.InstanceConfigs
-	}
-	return nil
-}
-
-func (x *Agent) GetCustomCommands() []*CommandInfo {
-	if x != nil {
-		return x.CustomCommands
-	}
-	return nil
-}
-
-type AgentConfigStatus struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Name    string       `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	Status  ConfigStatus `protobuf:"varint,2,opt,name=status,proto3,enum=ConfigStatus" json:"status,omitempty"` // Config's status
-	Message string       `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`                  // Optional error message
-}
-
-func (x *AgentConfigStatus) Reset() {
-	*x = AgentConfigStatus{}
-	mi := &file_user_proto_msgTypes[1]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *AgentConfigStatus) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*AgentConfigStatus) ProtoMessage() {}
-
-func (x *AgentConfigStatus) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[1]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use AgentConfigStatus.ProtoReflect.Descriptor instead.
-func (*AgentConfigStatus) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *AgentConfigStatus) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *AgentConfigStatus) GetStatus() ConfigStatus {
-	if x != nil {
-		return x.Status
-	}
-	return ConfigStatus_UNSET
-}
-
-func (x *AgentConfigStatus) GetMessage() string {
-	if x != nil {
-		return x.Message
-	}
-	return ""
-}
-
 type CreateAgentGroupRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -201,7 +116,7 @@ type CreateAgentGroupRequest struct {
 
 func (x *CreateAgentGroupRequest) Reset() {
 	*x = CreateAgentGroupRequest{}
-	mi := &file_user_proto_msgTypes[2]
+	mi := &file_user_proto_msgTypes[1]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -213,7 +128,7 @@ func (x *CreateAgentGroupRequest) String() string {
 func (*CreateAgentGroupRequest) ProtoMessage() {}
 
 func (x *CreateAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[2]
+	mi := &file_user_proto_msgTypes[1]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -226,7 +141,7 @@ func (x *CreateAgentGroupRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*CreateAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{2}
+	return file_user_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *CreateAgentGroupRequest) GetRequestId() []byte {
@@ -254,7 +169,7 @@ type CreateAgentGroupResponse struct {
 
 func (x *CreateAgentGroupResponse) Reset() {
 	*x = CreateAgentGroupResponse{}
-	mi := &file_user_proto_msgTypes[3]
+	mi := &file_user_proto_msgTypes[2]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -266,7 +181,7 @@ func (x *CreateAgentGroupResponse) String() string {
 func (*CreateAgentGroupResponse) ProtoMessage() {}
 
 func (x *CreateAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[3]
+	mi := &file_user_proto_msgTypes[2]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -279,7 +194,7 @@ func (x *CreateAgentGroupResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*CreateAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{3}
+	return file_user_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *CreateAgentGroupResponse) GetRequestId() []byte {
@@ -307,7 +222,7 @@ type UpdateAgentGroupRequest struct {
 
 func (x *UpdateAgentGroupRequest) Reset() {
 	*x = UpdateAgentGroupRequest{}
-	mi := &file_user_proto_msgTypes[4]
+	mi := &file_user_proto_msgTypes[3]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -319,7 +234,7 @@ func (x *UpdateAgentGroupRequest) String() string {
 func (*UpdateAgentGroupRequest) ProtoMessage() {}
 
 func (x *UpdateAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[4]
+	mi := &file_user_proto_msgTypes[3]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -332,7 +247,7 @@ func (x *UpdateAgentGroupRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*UpdateAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{4}
+	return file_user_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *UpdateAgentGroupRequest) GetRequestId() []byte {
@@ -360,7 +275,7 @@ type UpdateAgentGroupResponse struct {
 
 func (x *UpdateAgentGroupResponse) Reset() {
 	*x = UpdateAgentGroupResponse{}
-	mi := &file_user_proto_msgTypes[5]
+	mi := &file_user_proto_msgTypes[4]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -372,7 +287,7 @@ func (x *UpdateAgentGroupResponse) String() string {
 func (*UpdateAgentGroupResponse) ProtoMessage() {}
 
 func (x *UpdateAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[5]
+	mi := &file_user_proto_msgTypes[4]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -385,7 +300,7 @@ func (x *UpdateAgentGroupResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*UpdateAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{5}
+	return file_user_proto_rawDescGZIP(), []int{4}
 }
 
 func (x *UpdateAgentGroupResponse) GetRequestId() []byte {
@@ -413,7 +328,7 @@ type DeleteAgentGroupRequest struct {
 
 func (x *DeleteAgentGroupRequest) Reset() {
 	*x = DeleteAgentGroupRequest{}
-	mi := &file_user_proto_msgTypes[6]
+	mi := &file_user_proto_msgTypes[5]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -425,7 +340,7 @@ func (x *DeleteAgentGroupRequest) String() string {
 func (*DeleteAgentGroupRequest) ProtoMessage() {}
 
 func (x *DeleteAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[6]
+	mi := &file_user_proto_msgTypes[5]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -438,7 +353,7 @@ func (x *DeleteAgentGroupRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*DeleteAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{6}
+	return file_user_proto_rawDescGZIP(), []int{5}
 }
 
 func (x *DeleteAgentGroupRequest) GetRequestId() []byte {
@@ -466,7 +381,7 @@ type DeleteAgentGroupResponse struct {
 
 func (x *DeleteAgentGroupResponse) Reset() {
 	*x = DeleteAgentGroupResponse{}
-	mi := &file_user_proto_msgTypes[7]
+	mi := &file_user_proto_msgTypes[6]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -478,7 +393,7 @@ func (x *DeleteAgentGroupResponse) String() string {
 func (*DeleteAgentGroupResponse) ProtoMessage() {}
 
 func (x *DeleteAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[7]
+	mi := &file_user_proto_msgTypes[6]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -491,7 +406,7 @@ func (x *DeleteAgentGroupResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*DeleteAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{7}
+	return file_user_proto_rawDescGZIP(), []int{6}
 }
 
 func (x *DeleteAgentGroupResponse) GetRequestId() []byte {
@@ -519,7 +434,7 @@ type GetAgentGroupRequest struct {
 
 func (x *GetAgentGroupRequest) Reset() {
 	*x = GetAgentGroupRequest{}
-	mi := &file_user_proto_msgTypes[8]
+	mi := &file_user_proto_msgTypes[7]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -531,7 +446,7 @@ func (x *GetAgentGroupRequest) String() string {
 func (*GetAgentGroupRequest) ProtoMessage() {}
 
 func (x *GetAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[8]
+	mi := &file_user_proto_msgTypes[7]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -544,7 +459,7 @@ func (x *GetAgentGroupRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*GetAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{8}
+	return file_user_proto_rawDescGZIP(), []int{7}
 }
 
 func (x *GetAgentGroupRequest) GetRequestId() []byte {
@@ -573,7 +488,7 @@ type GetAgentGroupResponse struct {
 
 func (x *GetAgentGroupResponse) Reset() {
 	*x = GetAgentGroupResponse{}
-	mi := &file_user_proto_msgTypes[9]
+	mi := &file_user_proto_msgTypes[8]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -585,7 +500,7 @@ func (x *GetAgentGroupResponse) String() string {
 func (*GetAgentGroupResponse) ProtoMessage() {}
 
 func (x *GetAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[9]
+	mi := &file_user_proto_msgTypes[8]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -598,7 +513,7 @@ func (x *GetAgentGroupResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*GetAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{9}
+	return file_user_proto_rawDescGZIP(), []int{8}
 }
 
 func (x *GetAgentGroupResponse) GetRequestId() []byte {
@@ -632,7 +547,7 @@ type ListAgentGroupsRequest struct {
 
 func (x *ListAgentGroupsRequest) Reset() {
 	*x = ListAgentGroupsRequest{}
-	mi := &file_user_proto_msgTypes[10]
+	mi := &file_user_proto_msgTypes[9]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -644,7 +559,7 @@ func (x *ListAgentGroupsRequest) String() string {
 func (*ListAgentGroupsRequest) ProtoMessage() {}
 
 func (x *ListAgentGroupsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[10]
+	mi := &file_user_proto_msgTypes[9]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -657,7 +572,7 @@ func (x *ListAgentGroupsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListAgentGroupsRequest.ProtoReflect.Descriptor instead.
 func (*ListAgentGroupsRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{10}
+	return file_user_proto_rawDescGZIP(), []int{9}
 }
 
 func (x *ListAgentGroupsRequest) GetRequestId() []byte {
@@ -679,7 +594,7 @@ type ListAgentGroupsResponse struct {
 
 func (x *ListAgentGroupsResponse) Reset() {
 	*x = ListAgentGroupsResponse{}
-	mi := &file_user_proto_msgTypes[11]
+	mi := &file_user_proto_msgTypes[10]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -691,7 +606,7 @@ func (x *ListAgentGroupsResponse) String() string {
 func (*ListAgentGroupsResponse) ProtoMessage() {}
 
 func (x *ListAgentGroupsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[11]
+	mi := &file_user_proto_msgTypes[10]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -704,7 +619,7 @@ func (x *ListAgentGroupsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListAgentGroupsResponse.ProtoReflect.Descriptor instead.
 func (*ListAgentGroupsResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{11}
+	return file_user_proto_rawDescGZIP(), []int{10}
 }
 
 func (x *ListAgentGroupsResponse) GetRequestId() []byte {
@@ -741,7 +656,7 @@ type CreateConfigRequest struct {
 
 func (x *CreateConfigRequest) Reset() {
 	*x = CreateConfigRequest{}
-	mi := &file_user_proto_msgTypes[12]
+	mi := &file_user_proto_msgTypes[11]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -753,7 +668,7 @@ func (x *CreateConfigRequest) String() string {
 func (*CreateConfigRequest) ProtoMessage() {}
 
 func (x *CreateConfigRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[12]
+	mi := &file_user_proto_msgTypes[11]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -766,7 +681,7 @@ func (x *CreateConfigRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateConfigRequest.ProtoReflect.Descriptor instead.
 func (*CreateConfigRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{12}
+	return file_user_proto_rawDescGZIP(), []int{11}
 }
 
 func (x *CreateConfigRequest) GetRequestId() []byte {
@@ -794,7 +709,7 @@ type CreateConfigResponse struct {
 
 func (x *CreateConfigResponse) Reset() {
 	*x = CreateConfigResponse{}
-	mi := &file_user_proto_msgTypes[13]
+	mi := &file_user_proto_msgTypes[12]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -806,7 +721,7 @@ func (x *CreateConfigResponse) String() string {
 func (*CreateConfigResponse) ProtoMessage() {}
 
 func (x *CreateConfigResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[13]
+	mi := &file_user_proto_msgTypes[12]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -819,7 +734,7 @@ func (x *CreateConfigResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateConfigResponse.ProtoReflect.Descriptor instead.
 func (*CreateConfigResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{13}
+	return file_user_proto_rawDescGZIP(), []int{12}
 }
 
 func (x *CreateConfigResponse) GetRequestId() []byte {
@@ -849,7 +764,7 @@ type UpdateConfigRequest struct {
 
 func (x *UpdateConfigRequest) Reset() {
 	*x = UpdateConfigRequest{}
-	mi := &file_user_proto_msgTypes[14]
+	mi := &file_user_proto_msgTypes[13]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -861,7 +776,7 @@ func (x *UpdateConfigRequest) String() string {
 func (*UpdateConfigRequest) ProtoMessage() {}
 
 func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[14]
+	mi := &file_user_proto_msgTypes[13]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -874,7 +789,7 @@ func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateConfigRequest.ProtoReflect.Descriptor instead.
 func (*UpdateConfigRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{14}
+	return file_user_proto_rawDescGZIP(), []int{13}
 }
 
 func (x *UpdateConfigRequest) GetRequestId() []byte {
@@ -902,7 +817,7 @@ type UpdateConfigResponse struct {
 
 func (x *UpdateConfigResponse) Reset() {
 	*x = UpdateConfigResponse{}
-	mi := &file_user_proto_msgTypes[15]
+	mi := &file_user_proto_msgTypes[14]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -914,7 +829,7 @@ func (x *UpdateConfigResponse) String() string {
 func (*UpdateConfigResponse) ProtoMessage() {}
 
 func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[15]
+	mi := &file_user_proto_msgTypes[14]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -927,7 +842,7 @@ func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateConfigResponse.ProtoReflect.Descriptor instead.
 func (*UpdateConfigResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{15}
+	return file_user_proto_rawDescGZIP(), []int{14}
 }
 
 func (x *UpdateConfigResponse) GetRequestId() []byte {
@@ -957,7 +872,7 @@ type DeleteConfigRequest struct {
 
 func (x *DeleteConfigRequest) Reset() {
 	*x = DeleteConfigRequest{}
-	mi := &file_user_proto_msgTypes[16]
+	mi := &file_user_proto_msgTypes[15]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -969,7 +884,7 @@ func (x *DeleteConfigRequest) String() string {
 func (*DeleteConfigRequest) ProtoMessage() {}
 
 func (x *DeleteConfigRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[16]
+	mi := &file_user_proto_msgTypes[15]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -982,7 +897,7 @@ func (x *DeleteConfigRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteConfigRequest.ProtoReflect.Descriptor instead.
 func (*DeleteConfigRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{16}
+	return file_user_proto_rawDescGZIP(), []int{15}
 }
 
 func (x *DeleteConfigRequest) GetRequestId() []byte {
@@ -1010,7 +925,7 @@ type DeleteConfigResponse struct {
 
 func (x *DeleteConfigResponse) Reset() {
 	*x = DeleteConfigResponse{}
-	mi := &file_user_proto_msgTypes[17]
+	mi := &file_user_proto_msgTypes[16]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1022,7 +937,7 @@ func (x *DeleteConfigResponse) String() string {
 func (*DeleteConfigResponse) ProtoMessage() {}
 
 func (x *DeleteConfigResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[17]
+	mi := &file_user_proto_msgTypes[16]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1035,7 +950,7 @@ func (x *DeleteConfigResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteConfigResponse.ProtoReflect.Descriptor instead.
 func (*DeleteConfigResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{17}
+	return file_user_proto_rawDescGZIP(), []int{16}
 }
 
 func (x *DeleteConfigResponse) GetRequestId() []byte {
@@ -1065,7 +980,7 @@ type GetConfigRequest struct {
 
 func (x *GetConfigRequest) Reset() {
 	*x = GetConfigRequest{}
-	mi := &file_user_proto_msgTypes[18]
+	mi := &file_user_proto_msgTypes[17]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1077,7 +992,7 @@ func (x *GetConfigRequest) String() string {
 func (*GetConfigRequest) ProtoMessage() {}
 
 func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[18]
+	mi := &file_user_proto_msgTypes[17]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1090,7 +1005,7 @@ func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetConfigRequest.ProtoReflect.Descriptor instead.
 func (*GetConfigRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{18}
+	return file_user_proto_rawDescGZIP(), []int{17}
 }
 
 func (x *GetConfigRequest) GetRequestId() []byte {
@@ -1119,7 +1034,7 @@ type GetConfigResponse struct {
 
 func (x *GetConfigResponse) Reset() {
 	*x = GetConfigResponse{}
-	mi := &file_user_proto_msgTypes[19]
+	mi := &file_user_proto_msgTypes[18]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1131,7 +1046,7 @@ func (x *GetConfigResponse) String() string {
 func (*GetConfigResponse) ProtoMessage() {}
 
 func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[19]
+	mi := &file_user_proto_msgTypes[18]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1144,7 +1059,7 @@ func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetConfigResponse.ProtoReflect.Descriptor instead.
 func (*GetConfigResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{19}
+	return file_user_proto_rawDescGZIP(), []int{18}
 }
 
 func (x *GetConfigResponse) GetRequestId() []byte {
@@ -1181,7 +1096,7 @@ type GetConfigStatusListRequest struct {
 
 func (x *GetConfigStatusListRequest) Reset() {
 	*x = GetConfigStatusListRequest{}
-	mi := &file_user_proto_msgTypes[20]
+	mi := &file_user_proto_msgTypes[19]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1193,7 +1108,7 @@ func (x *GetConfigStatusListRequest) String() string {
 func (*GetConfigStatusListRequest) ProtoMessage() {}
 
 func (x *GetConfigStatusListRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[20]
+	mi := &file_user_proto_msgTypes[19]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1206,7 +1121,7 @@ func (x *GetConfigStatusListRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetConfigStatusListRequest.ProtoReflect.Descriptor instead.
 func (*GetConfigStatusListRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{20}
+	return file_user_proto_rawDescGZIP(), []int{19}
 }
 
 func (x *GetConfigStatusListRequest) GetRequestId() []byte {
@@ -1228,14 +1143,14 @@ type GetConfigStatusListResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestId         []byte               `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
-	CommonResponse    *CommonResponse      `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
-	AgentConfigStatus []*AgentConfigStatus `protobuf:"bytes,3,rep,name=agent_config_status,json=agentConfigStatus,proto3" json:"agent_config_status,omitempty"`
+	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
+	ConfigStatus   []*ConfigInfo   `protobuf:"bytes,3,rep,name=config_status,json=configStatus,proto3" json:"config_status,omitempty"`
 }
 
 func (x *GetConfigStatusListResponse) Reset() {
 	*x = GetConfigStatusListResponse{}
-	mi := &file_user_proto_msgTypes[21]
+	mi := &file_user_proto_msgTypes[20]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1247,7 +1162,7 @@ func (x *GetConfigStatusListResponse) String() string {
 func (*GetConfigStatusListResponse) ProtoMessage() {}
 
 func (x *GetConfigStatusListResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[21]
+	mi := &file_user_proto_msgTypes[20]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1260,7 +1175,7 @@ func (x *GetConfigStatusListResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetConfigStatusListResponse.ProtoReflect.Descriptor instead.
 func (*GetConfigStatusListResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{21}
+	return file_user_proto_rawDescGZIP(), []int{20}
 }
 
 func (x *GetConfigStatusListResponse) GetRequestId() []byte {
@@ -1277,9 +1192,9 @@ func (x *GetConfigStatusListResponse) GetCommonResponse() *CommonResponse {
 	return nil
 }
 
-func (x *GetConfigStatusListResponse) GetAgentConfigStatus() []*AgentConfigStatus {
+func (x *GetConfigStatusListResponse) GetConfigStatus() []*ConfigInfo {
 	if x != nil {
-		return x.AgentConfigStatus
+		return x.ConfigStatus
 	}
 	return nil
 }
@@ -1296,7 +1211,7 @@ type ListConfigsRequest struct {
 
 func (x *ListConfigsRequest) Reset() {
 	*x = ListConfigsRequest{}
-	mi := &file_user_proto_msgTypes[22]
+	mi := &file_user_proto_msgTypes[21]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1308,7 +1223,7 @@ func (x *ListConfigsRequest) String() string {
 func (*ListConfigsRequest) ProtoMessage() {}
 
 func (x *ListConfigsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[22]
+	mi := &file_user_proto_msgTypes[21]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1321,7 +1236,7 @@ func (x *ListConfigsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListConfigsRequest.ProtoReflect.Descriptor instead.
 func (*ListConfigsRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{22}
+	return file_user_proto_rawDescGZIP(), []int{21}
 }
 
 func (x *ListConfigsRequest) GetRequestId() []byte {
@@ -1343,7 +1258,7 @@ type ListConfigsResponse struct {
 
 func (x *ListConfigsResponse) Reset() {
 	*x = ListConfigsResponse{}
-	mi := &file_user_proto_msgTypes[23]
+	mi := &file_user_proto_msgTypes[22]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1355,7 +1270,7 @@ func (x *ListConfigsResponse) String() string {
 func (*ListConfigsResponse) ProtoMessage() {}
 
 func (x *ListConfigsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[23]
+	mi := &file_user_proto_msgTypes[22]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1368,7 +1283,7 @@ func (x *ListConfigsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListConfigsResponse.ProtoReflect.Descriptor instead.
 func (*ListConfigsResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{23}
+	return file_user_proto_rawDescGZIP(), []int{22}
 }
 
 func (x *ListConfigsResponse) GetRequestId() []byte {
@@ -1406,7 +1321,7 @@ type ApplyConfigToAgentGroupRequest struct {
 
 func (x *ApplyConfigToAgentGroupRequest) Reset() {
 	*x = ApplyConfigToAgentGroupRequest{}
-	mi := &file_user_proto_msgTypes[24]
+	mi := &file_user_proto_msgTypes[23]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1418,7 +1333,7 @@ func (x *ApplyConfigToAgentGroupRequest) String() string {
 func (*ApplyConfigToAgentGroupRequest) ProtoMessage() {}
 
 func (x *ApplyConfigToAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[24]
+	mi := &file_user_proto_msgTypes[23]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1431,7 +1346,7 @@ func (x *ApplyConfigToAgentGroupRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplyConfigToAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*ApplyConfigToAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{24}
+	return file_user_proto_rawDescGZIP(), []int{23}
 }
 
 func (x *ApplyConfigToAgentGroupRequest) GetRequestId() []byte {
@@ -1466,7 +1381,7 @@ type ApplyConfigToAgentGroupResponse struct {
 
 func (x *ApplyConfigToAgentGroupResponse) Reset() {
 	*x = ApplyConfigToAgentGroupResponse{}
-	mi := &file_user_proto_msgTypes[25]
+	mi := &file_user_proto_msgTypes[24]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1478,7 +1393,7 @@ func (x *ApplyConfigToAgentGroupResponse) String() string {
 func (*ApplyConfigToAgentGroupResponse) ProtoMessage() {}
 
 func (x *ApplyConfigToAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[25]
+	mi := &file_user_proto_msgTypes[24]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1491,7 +1406,7 @@ func (x *ApplyConfigToAgentGroupResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplyConfigToAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*ApplyConfigToAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{25}
+	return file_user_proto_rawDescGZIP(), []int{24}
 }
 
 func (x *ApplyConfigToAgentGroupResponse) GetRequestId() []byte {
@@ -1522,7 +1437,7 @@ type RemoveConfigFromAgentGroupRequest struct {
 
 func (x *RemoveConfigFromAgentGroupRequest) Reset() {
 	*x = RemoveConfigFromAgentGroupRequest{}
-	mi := &file_user_proto_msgTypes[26]
+	mi := &file_user_proto_msgTypes[25]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1534,7 +1449,7 @@ func (x *RemoveConfigFromAgentGroupRequest) String() string {
 func (*RemoveConfigFromAgentGroupRequest) ProtoMessage() {}
 
 func (x *RemoveConfigFromAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[26]
+	mi := &file_user_proto_msgTypes[25]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1547,7 +1462,7 @@ func (x *RemoveConfigFromAgentGroupRequest) ProtoReflect() protoreflect.Message
 
 // Deprecated: Use RemoveConfigFromAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*RemoveConfigFromAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{26}
+	return file_user_proto_rawDescGZIP(), []int{25}
 }
 
 func (x *RemoveConfigFromAgentGroupRequest) GetRequestId() []byte {
@@ -1582,7 +1497,7 @@ type RemoveConfigFromAgentGroupResponse struct {
 
 func (x *RemoveConfigFromAgentGroupResponse) Reset() {
 	*x = RemoveConfigFromAgentGroupResponse{}
-	mi := &file_user_proto_msgTypes[27]
+	mi := &file_user_proto_msgTypes[26]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1594,7 +1509,7 @@ func (x *RemoveConfigFromAgentGroupResponse) String() string {
 func (*RemoveConfigFromAgentGroupResponse) ProtoMessage() {}
 
 func (x *RemoveConfigFromAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[27]
+	mi := &file_user_proto_msgTypes[26]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1607,7 +1522,7 @@ func (x *RemoveConfigFromAgentGroupResponse) ProtoReflect() protoreflect.Message
 
 // Deprecated: Use RemoveConfigFromAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*RemoveConfigFromAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{27}
+	return file_user_proto_rawDescGZIP(), []int{26}
 }
 
 func (x *RemoveConfigFromAgentGroupResponse) GetRequestId() []byte {
@@ -1637,7 +1552,7 @@ type GetAppliedConfigsForAgentGroupRequest struct {
 
 func (x *GetAppliedConfigsForAgentGroupRequest) Reset() {
 	*x = GetAppliedConfigsForAgentGroupRequest{}
-	mi := &file_user_proto_msgTypes[28]
+	mi := &file_user_proto_msgTypes[27]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1649,7 +1564,7 @@ func (x *GetAppliedConfigsForAgentGroupRequest) String() string {
 func (*GetAppliedConfigsForAgentGroupRequest) ProtoMessage() {}
 
 func (x *GetAppliedConfigsForAgentGroupRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[28]
+	mi := &file_user_proto_msgTypes[27]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1662,7 +1577,7 @@ func (x *GetAppliedConfigsForAgentGroupRequest) ProtoReflect() protoreflect.Mess
 
 // Deprecated: Use GetAppliedConfigsForAgentGroupRequest.ProtoReflect.Descriptor instead.
 func (*GetAppliedConfigsForAgentGroupRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{28}
+	return file_user_proto_rawDescGZIP(), []int{27}
 }
 
 func (x *GetAppliedConfigsForAgentGroupRequest) GetRequestId() []byte {
@@ -1691,7 +1606,7 @@ type GetAppliedConfigsForAgentGroupResponse struct {
 
 func (x *GetAppliedConfigsForAgentGroupResponse) Reset() {
 	*x = GetAppliedConfigsForAgentGroupResponse{}
-	mi := &file_user_proto_msgTypes[29]
+	mi := &file_user_proto_msgTypes[28]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1703,7 +1618,7 @@ func (x *GetAppliedConfigsForAgentGroupResponse) String() string {
 func (*GetAppliedConfigsForAgentGroupResponse) ProtoMessage() {}
 
 func (x *GetAppliedConfigsForAgentGroupResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[29]
+	mi := &file_user_proto_msgTypes[28]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1716,7 +1631,7 @@ func (x *GetAppliedConfigsForAgentGroupResponse) ProtoReflect() protoreflect.Mes
 
 // Deprecated: Use GetAppliedConfigsForAgentGroupResponse.ProtoReflect.Descriptor instead.
 func (*GetAppliedConfigsForAgentGroupResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{29}
+	return file_user_proto_rawDescGZIP(), []int{28}
 }
 
 func (x *GetAppliedConfigsForAgentGroupResponse) GetRequestId() []byte {
@@ -1753,7 +1668,7 @@ type GetAppliedAgentGroupsRequest struct {
 
 func (x *GetAppliedAgentGroupsRequest) Reset() {
 	*x = GetAppliedAgentGroupsRequest{}
-	mi := &file_user_proto_msgTypes[30]
+	mi := &file_user_proto_msgTypes[29]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1765,7 +1680,7 @@ func (x *GetAppliedAgentGroupsRequest) String() string {
 func (*GetAppliedAgentGroupsRequest) ProtoMessage() {}
 
 func (x *GetAppliedAgentGroupsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[30]
+	mi := &file_user_proto_msgTypes[29]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1778,7 +1693,7 @@ func (x *GetAppliedAgentGroupsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAppliedAgentGroupsRequest.ProtoReflect.Descriptor instead.
 func (*GetAppliedAgentGroupsRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{30}
+	return file_user_proto_rawDescGZIP(), []int{29}
 }
 
 func (x *GetAppliedAgentGroupsRequest) GetRequestId() []byte {
@@ -1807,7 +1722,7 @@ type GetAppliedAgentGroupsResponse struct {
 
 func (x *GetAppliedAgentGroupsResponse) Reset() {
 	*x = GetAppliedAgentGroupsResponse{}
-	mi := &file_user_proto_msgTypes[31]
+	mi := &file_user_proto_msgTypes[30]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1819,7 +1734,7 @@ func (x *GetAppliedAgentGroupsResponse) String() string {
 func (*GetAppliedAgentGroupsResponse) ProtoMessage() {}
 
 func (x *GetAppliedAgentGroupsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[31]
+	mi := &file_user_proto_msgTypes[30]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1832,7 +1747,7 @@ func (x *GetAppliedAgentGroupsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetAppliedAgentGroupsResponse.ProtoReflect.Descriptor instead.
 func (*GetAppliedAgentGroupsResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{31}
+	return file_user_proto_rawDescGZIP(), []int{30}
 }
 
 func (x *GetAppliedAgentGroupsResponse) GetRequestId() []byte {
@@ -1867,7 +1782,7 @@ type ListAgentsRequest struct {
 
 func (x *ListAgentsRequest) Reset() {
 	*x = ListAgentsRequest{}
-	mi := &file_user_proto_msgTypes[32]
+	mi := &file_user_proto_msgTypes[31]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1879,7 +1794,7 @@ func (x *ListAgentsRequest) String() string {
 func (*ListAgentsRequest) ProtoMessage() {}
 
 func (x *ListAgentsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[32]
+	mi := &file_user_proto_msgTypes[31]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1892,7 +1807,7 @@ func (x *ListAgentsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListAgentsRequest.ProtoReflect.Descriptor instead.
 func (*ListAgentsRequest) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{32}
+	return file_user_proto_rawDescGZIP(), []int{31}
 }
 
 func (x *ListAgentsRequest) GetRequestId() []byte {
@@ -1921,7 +1836,7 @@ type ListAgentsResponse struct {
 
 func (x *ListAgentsResponse) Reset() {
 	*x = ListAgentsResponse{}
-	mi := &file_user_proto_msgTypes[33]
+	mi := &file_user_proto_msgTypes[32]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1933,7 +1848,7 @@ func (x *ListAgentsResponse) String() string {
 func (*ListAgentsResponse) ProtoMessage() {}
 
 func (x *ListAgentsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_user_proto_msgTypes[33]
+	mi := &file_user_proto_msgTypes[32]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1946,7 +1861,7 @@ func (x *ListAgentsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListAgentsResponse.ProtoReflect.Descriptor instead.
 func (*ListAgentsResponse) Descriptor() ([]byte, []int) {
-	return file_user_proto_rawDescGZIP(), []int{33}
+	return file_user_proto_rawDescGZIP(), []int{32}
 }
 
 func (x *ListAgentsResponse) GetRequestId() []byte {
@@ -1974,7 +1889,7 @@ var File_user_proto protoreflect.FileDescriptor
 
 var file_user_proto_rawDesc = []byte{
 	0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0b, 0x61, 0x67,
-	0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8e, 0x03, 0x0a, 0x05, 0x41, 0x67,
+	0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe7, 0x01, 0x0a, 0x05, 0x41, 0x67,
 	0x65, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
 	0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62,
 	0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61,
@@ -1989,262 +1904,244 @@ var file_user_proto_rawDesc = []byte{
 	0x09, 0x52, 0x0d, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
 	0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65,
 	0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x54,
-	0x69, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x10, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f,
-	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e,
-	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x70, 0x69, 0x70, 0x65,
-	0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x36, 0x0a, 0x10, 0x69,
-	0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18,
-	0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e,
-	0x66, 0x6f, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6f,
-	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x43,
-	0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74,
-	0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x68, 0x0a, 0x11, 0x41, 0x67,
-	0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
-	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
-	0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65,
-	0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73,
-	0x73, 0x61, 0x67, 0x65, 0x22, 0x69, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67,
-	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x2f,
-	0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
-	0x54, 0x61, 0x67, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22,
-	0x73, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
-	0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
-	0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f,
-	0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67,
-	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x2f,
-	0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
-	0x54, 0x61, 0x67, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22,
-	0x73, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
-	0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
-	0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f,
-	0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x57, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67,
-	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d,
-	0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x73, 0x0a,
-	0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
-	0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d,
-	0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x54, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
-	0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f,
-	0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67,
-	0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa1, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74,
-	0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
-	0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x0b, 0x61,
-	0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67,
-	0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x37, 0x0a, 0x16,
-	0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0xa5, 0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67,
-	0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64,
-	0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
-	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d,
-	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x0c, 0x61, 0x67,
-	0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67,
-	0x52, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x68, 0x0a,
-	0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
-	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65,
-	0x74, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x6f, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74,
-	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38,
-	0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x68, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61,
-	0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x32,
-	0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65,
-	0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
-	0x69, 0x6c, 0x22, 0x6f, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
+	0x69, 0x6d, 0x65, 0x22, 0x69, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65,
+	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
+	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x2f, 0x0a,
+	0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54,
+	0x61, 0x67, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x73,
+	0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f,
+	0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
 	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
 	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
 	0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
 	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
 	0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x22, 0x55, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
+	0x6e, 0x73, 0x65, 0x22, 0x69, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65,
+	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
+	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x2f, 0x0a,
+	0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54,
+	0x61, 0x67, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x73,
+	0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f,
+	0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
 	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
-	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x6f, 0x0a, 0x14, 0x44, 0x65,
-	0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
-	0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x0a, 0x10, 0x47,
-	0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f,
-	0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22,
-	0xa0, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x57, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67, 0x65,
+	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
+	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a,
+	0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x73, 0x0a, 0x18,
+	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
+	0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x22, 0x54, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f,
+	0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75,
+	0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72,
+	0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa1, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41,
+	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64,
+	0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
+	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d,
+	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x0b, 0x61, 0x67,
+	0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52,
+	0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x37, 0x0a, 0x16, 0x4c,
+	0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
 	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e,
-	0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e,
-	0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32,
-	0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65,
-	0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
-	0x69, 0x6c, 0x22, 0x5c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53,
-	0x74, 0x61, 0x74, 0x75, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12,
-	0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64,
-	0x22, 0xba, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74,
-	0x61, 0x74, 0x75, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x73, 0x74, 0x49, 0x64, 0x22, 0xa5, 0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65,
+	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
 	0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
 	0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12,
 	0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e,
 	0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f,
 	0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
-	0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x13, 0x61, 0x67, 0x65,
-	0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
-	0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x11, 0x61, 0x67, 0x65, 0x6e,
-	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x33, 0x0a,
-	0x12, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x0c, 0x61, 0x67, 0x65,
+	0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x0e, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52,
+	0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x68, 0x0a, 0x13,
+	0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75,
 	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
 	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x49, 0x64, 0x22, 0xa4, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65,
-	0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x7f, 0x0a, 0x1e, 0x41, 0x70, 0x70,
-	0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47,
-	0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
-	0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67,
-	0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7a, 0x0a, 0x1f, 0x41, 0x70,
-	0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74,
-	0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a,
-	0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f,
-	0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x21, 0x52, 0x65, 0x6d, 0x6f, 0x76,
-	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x74,
-	0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
-	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a,
-	0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7d, 0x0a, 0x22, 0x52,
-	0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x41,
-	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x49, 0x64, 0x12, 0x32, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74,
+	0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x6f, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d,
+	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a,
+	0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x68, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74,
+	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
+	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x32, 0x0a,
+	0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74,
+	0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x22, 0x6f, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d,
+	0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x55, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x6f, 0x0a, 0x14, 0x44, 0x65, 0x6c,
+	0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
 	0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18,
 	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64,
 	0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f,
 	0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
 	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d,
-	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x65, 0x0a, 0x25, 0x47, 0x65,
-	0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x46,
-	0x6f, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d,
-	0x65, 0x22, 0xa4, 0x01, 0x0a, 0x26, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64,
-	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x46, 0x6f, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47,
-	0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
-	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63,
-	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
-	0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x5e, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x41,
-	0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
-	0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
+	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x52, 0x0a, 0x10, 0x47, 0x65,
+	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
+	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a,
+	0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa0,
+	0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43,
+	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63,
+	0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a,
+	0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74,
+	0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x22, 0x5c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f,
+	0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22,
+	0xa8, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38,
+	0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x0b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x33, 0x0a, 0x12, 0x4c, 0x69,
+	0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22,
+	0xa4, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+	0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x34, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44,
+	0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x7f, 0x0a, 0x1e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
 	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65,
 	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69,
 	0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74,
-	0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
-	0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
+	0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75,
+	0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72,
+	0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7a, 0x0a, 0x1f, 0x41, 0x70, 0x70, 0x6c, 0x79,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f,
+	0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
 	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
 	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
 	0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
 	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
 	0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f,
-	0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f,
-	0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22,
-	0x51, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
-	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61,
-	0x6d, 0x65, 0x22, 0x8d, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74,
-	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x6e, 0x73, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x21, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f,
+	0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f,
+	0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67,
+	0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7d, 0x0a, 0x22, 0x52, 0x65, 0x6d, 0x6f,
+	0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x67, 0x65, 0x6e,
+	0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d,
+	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a,
+	0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x65, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x41, 0x70,
+	0x70, 0x6c, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x46, 0x6f, 0x72, 0x41,
+	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12,
+	0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa4,
+	0x01, 0x0a, 0x26, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x73, 0x46, 0x6f, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
 	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72,
 	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d,
 	0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
 	0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
 	0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x1e, 0x0a, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03,
-	0x28, 0x0b, 0x32, 0x06, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x61, 0x67, 0x65, 0x6e,
-	0x74, 0x73, 0x42, 0x0b, 0x5a, 0x09, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x76, 0x32, 0x3b, 0x62,
-	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d,
+	0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x5e, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c,
+	0x69, 0x65, 0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70,
+	0x6c, 0x69, 0x65, 0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
+	0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x2a, 0x0a, 0x11, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f,
+	0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x67, 0x65,
+	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x11,
+	0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64,
+	0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22,
+	0x8d, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f,
+	0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f,
+	0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52,
+	0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x1e, 0x0a, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x06, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x42,
+	0x0b, 0x5a, 0x09, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x76, 0x32, 0x3b, 0x62, 0x06, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -2259,87 +2156,80 @@ func file_user_proto_rawDescGZIP() []byte {
 	return file_user_proto_rawDescData
 }
 
-var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 34)
+var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 33)
 var file_user_proto_goTypes = []any{
 	(*Agent)(nil),                                  // 0: Agent
-	(*AgentConfigStatus)(nil),                      // 1: AgentConfigStatus
-	(*CreateAgentGroupRequest)(nil),                // 2: CreateAgentGroupRequest
-	(*CreateAgentGroupResponse)(nil),               // 3: CreateAgentGroupResponse
-	(*UpdateAgentGroupRequest)(nil),                // 4: UpdateAgentGroupRequest
-	(*UpdateAgentGroupResponse)(nil),               // 5: UpdateAgentGroupResponse
-	(*DeleteAgentGroupRequest)(nil),                // 6: DeleteAgentGroupRequest
-	(*DeleteAgentGroupResponse)(nil),               // 7: DeleteAgentGroupResponse
-	(*GetAgentGroupRequest)(nil),                   // 8: GetAgentGroupRequest
-	(*GetAgentGroupResponse)(nil),                  // 9: GetAgentGroupResponse
-	(*ListAgentGroupsRequest)(nil),                 // 10: ListAgentGroupsRequest
-	(*ListAgentGroupsResponse)(nil),                // 11: ListAgentGroupsResponse
-	(*CreateConfigRequest)(nil),                    // 12: CreateConfigRequest
-	(*CreateConfigResponse)(nil),                   // 13: CreateConfigResponse
-	(*UpdateConfigRequest)(nil),                    // 14: UpdateConfigRequest
-	(*UpdateConfigResponse)(nil),                   // 15: UpdateConfigResponse
-	(*DeleteConfigRequest)(nil),                    // 16: DeleteConfigRequest
-	(*DeleteConfigResponse)(nil),                   // 17: DeleteConfigResponse
-	(*GetConfigRequest)(nil),                       // 18: GetConfigRequest
-	(*GetConfigResponse)(nil),                      // 19: GetConfigResponse
-	(*GetConfigStatusListRequest)(nil),             // 20: GetConfigStatusListRequest
-	(*GetConfigStatusListResponse)(nil),            // 21: GetConfigStatusListResponse
-	(*ListConfigsRequest)(nil),                     // 22: ListConfigsRequest
-	(*ListConfigsResponse)(nil),                    // 23: ListConfigsResponse
-	(*ApplyConfigToAgentGroupRequest)(nil),         // 24: ApplyConfigToAgentGroupRequest
-	(*ApplyConfigToAgentGroupResponse)(nil),        // 25: ApplyConfigToAgentGroupResponse
-	(*RemoveConfigFromAgentGroupRequest)(nil),      // 26: RemoveConfigFromAgentGroupRequest
-	(*RemoveConfigFromAgentGroupResponse)(nil),     // 27: RemoveConfigFromAgentGroupResponse
-	(*GetAppliedConfigsForAgentGroupRequest)(nil),  // 28: GetAppliedConfigsForAgentGroupRequest
-	(*GetAppliedConfigsForAgentGroupResponse)(nil), // 29: GetAppliedConfigsForAgentGroupResponse
-	(*GetAppliedAgentGroupsRequest)(nil),           // 30: GetAppliedAgentGroupsRequest
-	(*GetAppliedAgentGroupsResponse)(nil),          // 31: GetAppliedAgentGroupsResponse
-	(*ListAgentsRequest)(nil),                      // 32: ListAgentsRequest
-	(*ListAgentsResponse)(nil),                     // 33: ListAgentsResponse
-	(*AgentAttributes)(nil),                        // 34: AgentAttributes
-	(*ConfigInfo)(nil),                             // 35: ConfigInfo
-	(*CommandInfo)(nil),                            // 36: CommandInfo
-	(ConfigStatus)(0),                              // 37: ConfigStatus
-	(*AgentGroupTag)(nil),                          // 38: AgentGroupTag
-	(*CommonResponse)(nil),                         // 39: CommonResponse
-	(*ConfigDetail)(nil),                           // 40: ConfigDetail
+	(*CreateAgentGroupRequest)(nil),                // 1: CreateAgentGroupRequest
+	(*CreateAgentGroupResponse)(nil),               // 2: CreateAgentGroupResponse
+	(*UpdateAgentGroupRequest)(nil),                // 3: UpdateAgentGroupRequest
+	(*UpdateAgentGroupResponse)(nil),               // 4: UpdateAgentGroupResponse
+	(*DeleteAgentGroupRequest)(nil),                // 5: DeleteAgentGroupRequest
+	(*DeleteAgentGroupResponse)(nil),               // 6: DeleteAgentGroupResponse
+	(*GetAgentGroupRequest)(nil),                   // 7: GetAgentGroupRequest
+	(*GetAgentGroupResponse)(nil),                  // 8: GetAgentGroupResponse
+	(*ListAgentGroupsRequest)(nil),                 // 9: ListAgentGroupsRequest
+	(*ListAgentGroupsResponse)(nil),                // 10: ListAgentGroupsResponse
+	(*CreateConfigRequest)(nil),                    // 11: CreateConfigRequest
+	(*CreateConfigResponse)(nil),                   // 12: CreateConfigResponse
+	(*UpdateConfigRequest)(nil),                    // 13: UpdateConfigRequest
+	(*UpdateConfigResponse)(nil),                   // 14: UpdateConfigResponse
+	(*DeleteConfigRequest)(nil),                    // 15: DeleteConfigRequest
+	(*DeleteConfigResponse)(nil),                   // 16: DeleteConfigResponse
+	(*GetConfigRequest)(nil),                       // 17: GetConfigRequest
+	(*GetConfigResponse)(nil),                      // 18: GetConfigResponse
+	(*GetConfigStatusListRequest)(nil),             // 19: GetConfigStatusListRequest
+	(*GetConfigStatusListResponse)(nil),            // 20: GetConfigStatusListResponse
+	(*ListConfigsRequest)(nil),                     // 21: ListConfigsRequest
+	(*ListConfigsResponse)(nil),                    // 22: ListConfigsResponse
+	(*ApplyConfigToAgentGroupRequest)(nil),         // 23: ApplyConfigToAgentGroupRequest
+	(*ApplyConfigToAgentGroupResponse)(nil),        // 24: ApplyConfigToAgentGroupResponse
+	(*RemoveConfigFromAgentGroupRequest)(nil),      // 25: RemoveConfigFromAgentGroupRequest
+	(*RemoveConfigFromAgentGroupResponse)(nil),     // 26: RemoveConfigFromAgentGroupResponse
+	(*GetAppliedConfigsForAgentGroupRequest)(nil),  // 27: GetAppliedConfigsForAgentGroupRequest
+	(*GetAppliedConfigsForAgentGroupResponse)(nil), // 28: GetAppliedConfigsForAgentGroupResponse
+	(*GetAppliedAgentGroupsRequest)(nil),           // 29: GetAppliedAgentGroupsRequest
+	(*GetAppliedAgentGroupsResponse)(nil),          // 30: GetAppliedAgentGroupsResponse
+	(*ListAgentsRequest)(nil),                      // 31: ListAgentsRequest
+	(*ListAgentsResponse)(nil),                     // 32: ListAgentsResponse
+	(*AgentAttributes)(nil),                        // 33: AgentAttributes
+	(*AgentGroupTag)(nil),                          // 34: AgentGroupTag
+	(*CommonResponse)(nil),                         // 35: CommonResponse
+	(*ConfigDetail)(nil),                           // 36: ConfigDetail
+	(*ConfigInfo)(nil),                             // 37: ConfigInfo
 }
 var file_user_proto_depIdxs = []int32{
-	34, // 0: Agent.attributes:type_name -> AgentAttributes
-	35, // 1: Agent.pipeline_configs:type_name -> ConfigInfo
-	35, // 2: Agent.instance_configs:type_name -> ConfigInfo
-	36, // 3: Agent.custom_commands:type_name -> CommandInfo
-	37, // 4: AgentConfigStatus.status:type_name -> ConfigStatus
-	38, // 5: CreateAgentGroupRequest.agent_group:type_name -> AgentGroupTag
-	39, // 6: CreateAgentGroupResponse.common_response:type_name -> CommonResponse
-	38, // 7: UpdateAgentGroupRequest.agent_group:type_name -> AgentGroupTag
-	39, // 8: UpdateAgentGroupResponse.common_response:type_name -> CommonResponse
-	39, // 9: DeleteAgentGroupResponse.common_response:type_name -> CommonResponse
-	39, // 10: GetAgentGroupResponse.common_response:type_name -> CommonResponse
-	38, // 11: GetAgentGroupResponse.agent_group:type_name -> AgentGroupTag
-	39, // 12: ListAgentGroupsResponse.common_response:type_name -> CommonResponse
-	38, // 13: ListAgentGroupsResponse.agent_groups:type_name -> AgentGroupTag
-	40, // 14: CreateConfigRequest.config_detail:type_name -> ConfigDetail
-	39, // 15: CreateConfigResponse.common_response:type_name -> CommonResponse
-	40, // 16: UpdateConfigRequest.config_detail:type_name -> ConfigDetail
-	39, // 17: UpdateConfigResponse.common_response:type_name -> CommonResponse
-	39, // 18: DeleteConfigResponse.common_response:type_name -> CommonResponse
-	39, // 19: GetConfigResponse.common_response:type_name -> CommonResponse
-	40, // 20: GetConfigResponse.config_detail:type_name -> ConfigDetail
-	39, // 21: GetConfigStatusListResponse.common_response:type_name -> CommonResponse
-	1,  // 22: GetConfigStatusListResponse.agent_config_status:type_name -> AgentConfigStatus
-	39, // 23: ListConfigsResponse.common_response:type_name -> CommonResponse
-	40, // 24: ListConfigsResponse.config_details:type_name -> ConfigDetail
-	39, // 25: ApplyConfigToAgentGroupResponse.common_response:type_name -> CommonResponse
-	39, // 26: RemoveConfigFromAgentGroupResponse.common_response:type_name -> CommonResponse
-	39, // 27: GetAppliedConfigsForAgentGroupResponse.common_response:type_name -> CommonResponse
-	39, // 28: GetAppliedAgentGroupsResponse.common_response:type_name -> CommonResponse
-	39, // 29: ListAgentsResponse.common_response:type_name -> CommonResponse
-	0,  // 30: ListAgentsResponse.agents:type_name -> Agent
-	31, // [31:31] is the sub-list for method output_type
-	31, // [31:31] is the sub-list for method input_type
-	31, // [31:31] is the sub-list for extension type_name
-	31, // [31:31] is the sub-list for extension extendee
-	0,  // [0:31] is the sub-list for field type_name
+	33, // 0: Agent.attributes:type_name -> AgentAttributes
+	34, // 1: CreateAgentGroupRequest.agent_group:type_name -> AgentGroupTag
+	35, // 2: CreateAgentGroupResponse.common_response:type_name -> CommonResponse
+	34, // 3: UpdateAgentGroupRequest.agent_group:type_name -> AgentGroupTag
+	35, // 4: UpdateAgentGroupResponse.common_response:type_name -> CommonResponse
+	35, // 5: DeleteAgentGroupResponse.common_response:type_name -> CommonResponse
+	35, // 6: GetAgentGroupResponse.common_response:type_name -> CommonResponse
+	34, // 7: GetAgentGroupResponse.agent_group:type_name -> AgentGroupTag
+	35, // 8: ListAgentGroupsResponse.common_response:type_name -> CommonResponse
+	34, // 9: ListAgentGroupsResponse.agent_groups:type_name -> AgentGroupTag
+	36, // 10: CreateConfigRequest.config_detail:type_name -> ConfigDetail
+	35, // 11: CreateConfigResponse.common_response:type_name -> CommonResponse
+	36, // 12: UpdateConfigRequest.config_detail:type_name -> ConfigDetail
+	35, // 13: UpdateConfigResponse.common_response:type_name -> CommonResponse
+	35, // 14: DeleteConfigResponse.common_response:type_name -> CommonResponse
+	35, // 15: GetConfigResponse.common_response:type_name -> CommonResponse
+	36, // 16: GetConfigResponse.config_detail:type_name -> ConfigDetail
+	35, // 17: GetConfigStatusListResponse.common_response:type_name -> CommonResponse
+	37, // 18: GetConfigStatusListResponse.config_status:type_name -> ConfigInfo
+	35, // 19: ListConfigsResponse.common_response:type_name -> CommonResponse
+	36, // 20: ListConfigsResponse.config_details:type_name -> ConfigDetail
+	35, // 21: ApplyConfigToAgentGroupResponse.common_response:type_name -> CommonResponse
+	35, // 22: RemoveConfigFromAgentGroupResponse.common_response:type_name -> CommonResponse
+	35, // 23: GetAppliedConfigsForAgentGroupResponse.common_response:type_name -> CommonResponse
+	35, // 24: GetAppliedAgentGroupsResponse.common_response:type_name -> CommonResponse
+	35, // 25: ListAgentsResponse.common_response:type_name -> CommonResponse
+	0,  // 26: ListAgentsResponse.agents:type_name -> Agent
+	27, // [27:27] is the sub-list for method output_type
+	27, // [27:27] is the sub-list for method input_type
+	27, // [27:27] is the sub-list for extension type_name
+	27, // [27:27] is the sub-list for extension extendee
+	0,  // [0:27] is the sub-list for field type_name
 }
 
 func init() { file_user_proto_init() }
@@ -2354,7 +2244,7 @@ func file_user_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_user_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   34,
+			NumMessages:   33,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
diff --git a/config_server/service/repository/agent.go b/config_server/service/repository/agent.go
index 0c857a10f2..927e24b080 100644
--- a/config_server/service/repository/agent.go
+++ b/config_server/service/repository/agent.go
@@ -8,13 +8,18 @@ import (
 
 var s = store.S
 
-func GetAgentByiId(instanceId string) *entity.Agent {
-	var agentInfo = new(entity.Agent)
-	row := s.Db.Where("instance_id=?", instanceId).Find(agentInfo).RowsAffected
-	if row == 1 {
-		return agentInfo
+func GetAgentByID(instanceId string, fields ...string) (*entity.Agent, error) {
+	var agentInfo = &entity.Agent{}
+	var row int64
+	if fields == nil || len(fields) == 0 {
+		row = s.Db.Where("instance_id=?", instanceId).Find(agentInfo).RowsAffected
+	} else {
+		row = s.Db.Select(fields).Where("instance_id=?", instanceId).Find(agentInfo).RowsAffected
 	}
-	return nil
+	if row != 1 {
+		return agentInfo, common.ServerErrorWithMsg(common.AgentNotExist, "instanceId=%s not exists", instanceId)
+	}
+	return agentInfo, nil
 }
 
 func GetAllAgents(containPipelineConfigs bool, containInstanceConfigs bool) []entity.Agent {
@@ -33,7 +38,7 @@ func GetAllAgents(containPipelineConfigs bool, containInstanceConfigs bool) []en
 func RemoveAgentById(instanceId string) error {
 	tx := s.Db.Where("instance_id=?", instanceId).Delete(&entity.Agent{})
 	if tx.RowsAffected != 1 {
-		return common.ServerErrorWithMsg("Agent failed to delete record %s", instanceId)
+		return common.ServerErrorWithMsg(common.AgentNotExist, "Agent failed to delete record %s", instanceId)
 	}
 	return nil
 }
diff --git a/config_server/service/repository/agent_group.go b/config_server/service/repository/agent_group.go
index dae459c1c9..3954092fe4 100644
--- a/config_server/service/repository/agent_group.go
+++ b/config_server/service/repository/agent_group.go
@@ -8,7 +8,7 @@ import (
 func CreateAgentGroup(group *entity.AgentGroup) error {
 	row := s.Db.Create(group).RowsAffected
 	if row != 1 {
-		return common.ServerErrorWithMsg("create agentGroup(%s) error", group.Name)
+		return common.ServerErrorWithMsg(common.AgentGroupAlreadyExist, "create agentGroup(%s) error", group.Name)
 	}
 	return nil
 }
@@ -21,7 +21,7 @@ func UpdateAgentGroup(group *entity.AgentGroup) error {
 func DeleteAgentGroup(name string) error {
 	row := s.Db.Where("name=?", name).Delete(&entity.AgentGroup{}).RowsAffected
 	if row != 1 {
-		return common.ServerErrorWithMsg("delete agentGroup(name=%s) error", name)
+		return common.ServerErrorWithMsg(common.AgentGroupNotExist, "delete agentGroup(name=%s) error", name)
 	}
 	return nil
 }
@@ -37,7 +37,7 @@ func GetAgentGroupDetail(name string, containPipelineConfigs bool, containInstan
 	}
 	row := tx.Find(agentGroup).RowsAffected
 	if row != 1 {
-		return nil, common.ServerErrorWithMsg("get agentGroup(name=%s) error", name)
+		return nil, common.ServerErrorWithMsg(common.AgentGroupNotExist, "get agentGroup(name=%s) error", name)
 	}
 	return agentGroup, nil
 }
@@ -68,7 +68,7 @@ func GetAppliedAgentGroupForPipelineConfigName(configName string) ([]string, err
 	pipelineConfig := &entity.PipelineConfig{}
 	row := s.Db.Preload("AgentGroups").Where("name=?", configName).Find(&pipelineConfig).RowsAffected
 	if row != 1 {
-		return nil, common.ServerErrorWithMsg("can not find name=%s pipelineConfig")
+		return nil, common.ServerErrorWithMsg(common.AgentGroupNotExist, "can not find name=%s pipelineConfig")
 	}
 	groupNames := make([]string, 0)
 	for _, group := range pipelineConfig.AgentGroups {
@@ -80,7 +80,7 @@ func GetAppliedAgentGroupForInstanceConfigName(configName string) ([]string, err
 	instanceConfig := &entity.InstanceConfig{}
 	row := s.Db.Preload("AgentGroups").Where("name=?", configName).Find(&instanceConfig).RowsAffected
 	if row != 1 {
-		return nil, common.ServerErrorWithMsg("can not find name=%s pipelineConfig")
+		return nil, common.ServerErrorWithMsg(common.ConfigNotExist, "can not find name=%s pipelineConfig")
 	}
 	groupNames := make([]string, 0)
 	for _, group := range instanceConfig.AgentGroups {
diff --git a/config_server/service/repository/base.go b/config_server/service/repository/base.go
index 7b619847d1..1b76f81779 100644
--- a/config_server/service/repository/base.go
+++ b/config_server/service/repository/base.go
@@ -20,7 +20,7 @@ func generateClauseColumn(names ...string) []clause.Column {
 
 func createOrUpdateEntities[T any](conflictColumnNames []string, assignmentColumns []string, entities ...T) error {
 	if conflictColumnNames == nil {
-		return common.ServerErrorWithMsg("conflictColumnNames could not be null")
+		panic("conflictColumnNames could not be null")
 	}
 	if entities == nil || len(entities) == 0 {
 		return nil
diff --git a/config_server/service/repository/instance_config.go b/config_server/service/repository/instance_config.go
index 5dd6535b6b..28d40b288e 100644
--- a/config_server/service/repository/instance_config.go
+++ b/config_server/service/repository/instance_config.go
@@ -9,7 +9,7 @@ func GetInstanceConfigByNames(names ...string) ([]*entity.InstanceConfig, error)
 	instanceConfigs := make([]*entity.InstanceConfig, 0)
 	row := s.Db.Where("name in (?)", names).Find(&instanceConfigs).RowsAffected
 	if row != int64(len(names)) {
-		return nil, common.ServerErrorWithMsg("instanceNames=%s can not be found", names)
+		return nil, common.ServerErrorWithMsg(common.ConfigNotExist, "instanceNames=%s can not be found", names)
 	}
 	return instanceConfigs, nil
 }
@@ -22,7 +22,7 @@ func GetInstanceConfigsByAgent(agent *entity.Agent) error {
 func CreateInstanceConfig(config *entity.InstanceConfig) error {
 	row := s.Db.Create(config).RowsAffected
 	if row != 1 {
-		return common.ServerErrorWithMsg("create InstanceConfig(%s) error", config.Name)
+		return common.ServerErrorWithMsg(common.ConfigAlreadyExist, "create InstanceConfig(%s) error", config.Name)
 	}
 	return nil
 }
@@ -35,7 +35,7 @@ func UpdateInstanceConfig(config *entity.InstanceConfig) error {
 func DeleteInstanceConfig(configName string) error {
 	row := s.Db.Where("name=?", configName).Delete(&entity.InstanceConfig{}).RowsAffected
 	if row != 1 {
-		return common.ServerErrorWithMsg("delete InstanceConfig(name=%s) error", configName)
+		return common.ServerErrorWithMsg(common.ConfigNotExist, "delete InstanceConfig(name=%s) error", configName)
 	}
 	return nil
 }
@@ -44,7 +44,7 @@ func GetInstanceConfig(configName string) (*entity.InstanceConfig, error) {
 	config := &entity.InstanceConfig{}
 	row := s.Db.Where("name=?", configName).Find(config).RowsAffected
 	if row != 1 {
-		return nil, common.ServerErrorWithMsg("get instanceConfig(name=%s) error", configName)
+		return nil, common.ServerErrorWithMsg(common.ConfigNotExist, "get instanceConfig(name=%s) error", configName)
 	}
 	return config, nil
 }
diff --git a/config_server/service/repository/pipeline_config.go b/config_server/service/repository/pipeline_config.go
index c570b0fa49..7d0b0ea3b6 100644
--- a/config_server/service/repository/pipeline_config.go
+++ b/config_server/service/repository/pipeline_config.go
@@ -9,7 +9,7 @@ func GetPipelineConfigByNames(names ...string) ([]*entity.PipelineConfig, error)
 	pipelineConfigs := make([]*entity.PipelineConfig, 0)
 	row := s.Db.Where("name in (?)", names).Find(&pipelineConfigs).RowsAffected
 	if row != int64(len(names)) {
-		return nil, common.ServerErrorWithMsg("pipelineNames=%s can not be found", names)
+		return nil, common.ServerErrorWithMsg(common.ConfigNotExist, "pipelineNames=%s can not be found", names)
 	}
 	return pipelineConfigs, nil
 }
@@ -22,7 +22,7 @@ func GetPipelineConfigsByAgent(agent *entity.Agent) error {
 func CreatePipelineConfig(config *entity.PipelineConfig) error {
 	row := s.Db.Create(config).RowsAffected
 	if row != 1 {
-		return common.ServerErrorWithMsg("create pipelineConfig(%s) error", config.Name)
+		return common.ServerErrorWithMsg(common.ConfigAlreadyExist, "create pipelineConfig(%s) error", config.Name)
 	}
 	return nil
 }
@@ -35,7 +35,7 @@ func UpdatePipelineConfig(config *entity.PipelineConfig) error {
 func DeletePipelineConfig(configName string) error {
 	row := s.Db.Where("name=?", configName).Delete(&entity.PipelineConfig{}).RowsAffected
 	if row != 1 {
-		return common.ServerErrorWithMsg("delete pipelineConfig(name=%s) error", configName)
+		return common.ServerErrorWithMsg(common.ConfigNotExist, "delete pipelineConfig(name=%s) error", configName)
 	}
 	return nil
 }
@@ -44,7 +44,7 @@ func GetPipelineConfig(configName string) (*entity.PipelineConfig, error) {
 	config := &entity.PipelineConfig{}
 	row := s.Db.Where("name=?", configName).Find(config).RowsAffected
 	if row != 1 {
-		return nil, common.ServerErrorWithMsg("delete pipelineConfig(name=%s) error", configName)
+		return nil, common.ServerErrorWithMsg(common.ConfigNotExist, "delete pipelineConfig(name=%s) error", configName)
 	}
 	return config, nil
 }
diff --git a/config_server/service/router/router.go b/config_server/service/router/router.go
index 87e8d36a1f..e2a51e3a18 100644
--- a/config_server/service/router/router.go
+++ b/config_server/service/router/router.go
@@ -25,6 +25,7 @@ func initUserRouter(router *gin.Engine) {
 		userRouter.POST("/ApplyPipelineConfigToAgentGroup", handler.ApplyPipelineConfigToAgentGroup)
 		userRouter.POST("/RemovePipelineConfigFromAgentGroup", handler.RemovePipelineConfigFromAgentGroup)
 		userRouter.POST("/GetAppliedAgentGroupsWithPipelineConfig", handler.GetAppliedAgentGroupsWithPipelineConfig)
+		userRouter.POST("/GetPipelineConfigStatusList", handler.GetPipelineConfigStatusList)
 
 		userRouter.POST("/CreateInstanceConfig", handler.CreateInstanceConfig)
 		userRouter.POST("/UpdateInstanceConfig", handler.UpdateInstanceConfig)
@@ -34,6 +35,7 @@ func initUserRouter(router *gin.Engine) {
 		userRouter.POST("/ApplyInstanceConfigToAgentGroup", handler.ApplyInstanceConfigToAgentGroup)
 		userRouter.POST("/RemoveInstanceConfigFromAgentGroup", handler.RemoveInstanceConfigFromAgentGroup)
 		userRouter.POST("/GetAppliedAgentGroupsWithInstanceConfig", handler.GetAppliedAgentGroupsWithInstanceConfig)
+		userRouter.POST("/GetInstanceConfigStatusList", handler.GetInstanceConfigStatusList)
 	}
 
 }
diff --git a/config_server/service/service/agent.go b/config_server/service/service/agent.go
index 48e8712334..81b20a66ed 100644
--- a/config_server/service/service/agent.go
+++ b/config_server/service/service/agent.go
@@ -54,8 +54,8 @@ func HeartBeat(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error
 
 	var err error
 	sequenceNum := req.SequenceNum
-
-	rationality := manager.JudgeSequenceNumRationality(instanceId, sequenceNum)
+	var strInstanceId = string(instanceId)
+	rationality := manager.JudgeSequenceNumRationality(strInstanceId, sequenceNum)
 
 	//假设数据库保存的sequenceNum=3,agent给的是10,
 	//如果在判断rationality=false立即return,数据库中保存的一直是3,agent一直重传全部状态
@@ -83,7 +83,6 @@ func HeartBeat(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error
 	if err != nil {
 		return common.SystemError(err)
 	}
-
 	return nil
 }
 
diff --git a/config_server/service/service/agent_group.go b/config_server/service/service/agent_group.go
index 5633f2bac3..2784cce264 100644
--- a/config_server/service/service/agent_group.go
+++ b/config_server/service/service/agent_group.go
@@ -3,7 +3,6 @@ package service
 import (
 	"config-server/common"
 	"config-server/entity"
-
 	proto "config-server/protov2"
 	"config-server/repository"
 	"config-server/utils"
@@ -39,7 +38,7 @@ func DeleteAgentGroup(req *proto.DeleteAgentGroupRequest, res *proto.DeleteAgent
 		return common.ValidateErrorWithMsg("required field groupName could not be null")
 	}
 	if req.GroupName == entity.AgentGroupDefaultValue {
-		return common.ServerErrorWithMsg("%s can not be deleted", entity.AgentGroupDefaultValue)
+		return common.ServerErrorWithMsg(common.AgentGroupNotExist, "%s can not be deleted", entity.AgentGroupDefaultValue)
 	}
 	err := repository.DeleteAgentGroup(agentGroupName)
 	return common.SystemError(err)
diff --git a/config_server/service/service/instance_config.go b/config_server/service/service/instance_config.go
index 890a73145b..eb817b5f6c 100644
--- a/config_server/service/service/instance_config.go
+++ b/config_server/service/service/instance_config.go
@@ -125,3 +125,16 @@ func GetAppliedInstanceConfigsForAgentGroup(req *proto.GetAppliedConfigsForAgent
 	res.ConfigNames = configNames
 	return nil
 }
+
+func GetInstanceConfigStatusList(req *proto.GetConfigStatusListRequest, res *proto.GetConfigStatusListResponse) error {
+	instanceId := req.InstanceId
+	if instanceId == nil {
+		return common.ValidateErrorWithMsg("required fields instanceId could not be null")
+	}
+	agent, err := repository.GetAgentByID(string(instanceId), "instance_id", "instance_config_statuses")
+	if err != nil {
+		return common.SystemError(err)
+	}
+	res.ConfigStatus = agent.InstanceConfigStatuses.Parse2ProtoConfigStatus()
+	return nil
+}
diff --git a/config_server/service/service/pipeline_config.go b/config_server/service/service/pipeline_config.go
index 52bb5b3dc1..b09149b2be 100644
--- a/config_server/service/service/pipeline_config.go
+++ b/config_server/service/service/pipeline_config.go
@@ -129,3 +129,16 @@ func GetAppliedPipelineConfigsForAgentGroup(req *proto.GetAppliedConfigsForAgent
 	res.ConfigNames = configNames
 	return nil
 }
+
+func GetPipelineConfigStatusList(req *proto.GetConfigStatusListRequest, res *proto.GetConfigStatusListResponse) error {
+	instanceId := req.InstanceId
+	if instanceId == nil {
+		return common.ValidateErrorWithMsg("required fields instanceId could not be null")
+	}
+	agent, err := repository.GetAgentByID(string(instanceId), "instance_id", "pipeline_config_statuses")
+	if err != nil {
+		return common.SystemError(err)
+	}
+	res.ConfigStatus = agent.PipelineConfigStatuses.Parse2ProtoConfigStatus()
+	return nil
+}

From a33a26b4facffc3dd068ee8a82487a74d31d61f5 Mon Sep 17 00:00:00 2001
From: ww67652 <1749113286@qq.com>
Date: Mon, 28 Oct 2024 13:03:19 +0800
Subject: [PATCH 07/11] feat: Distinguish between test API and logs based on
 the environment (dev prod)

---
 config_server/service/cmd/main.go      | 13 +++++++++++--
 config_server/service/router/router.go |  6 ++++--
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/config_server/service/cmd/main.go b/config_server/service/cmd/main.go
index 0c68566c45..0cb9dcec42 100644
--- a/config_server/service/cmd/main.go
+++ b/config_server/service/cmd/main.go
@@ -4,11 +4,20 @@ import (
 	"config-server/config"
 	"config-server/router"
 	"github.com/gin-gonic/gin"
+	"os"
 )
 
 func main() {
-	r := gin.Default()
-	router.InitAllRouter(r)
+	env := os.Getenv("GO_ENV")
+	var r *gin.Engine
+	if env == "prod" {
+		gin.SetMode(gin.ReleaseMode)
+		r = gin.New()
+	} else {
+		gin.SetMode(gin.DebugMode)
+		r = gin.Default()
+	}
+	router.InitAllRouter(r, env)
 	err := r.Run(config.ServerConfigInstance.Address)
 	if err != nil {
 		panic(err)
diff --git a/config_server/service/router/router.go b/config_server/service/router/router.go
index e2a51e3a18..23d3de83f2 100644
--- a/config_server/service/router/router.go
+++ b/config_server/service/router/router.go
@@ -61,8 +61,10 @@ func initTest(router *gin.Engine) {
 	}
 }
 
-func InitAllRouter(router *gin.Engine) {
+func InitAllRouter(router *gin.Engine, env string) {
 	initAgentRouter(router)
 	initUserRouter(router)
-	initTest(router)
+	if env != "prod" {
+		initTest(router)
+	}
 }

From 2bee0b5f5317090ad0670f35e7757fe1684545b4 Mon Sep 17 00:00:00 2001
From: ww67652 <1749113286@qq.com>
Date: Wed, 30 Oct 2024 12:55:20 +0800
Subject: [PATCH 08/11] refactor service directory

---
 config_server/service/cmd/env.json            |    3 -
 .../service/entity/agent_and_config.go        |   81 -
 config_server/service/entity/config.go        |   75 -
 .../service/manager/capability/agent.go       |   88 -
 .../service/manager/capability/common.go      |   23 -
 .../service/manager/capability/server.go      |  112 -
 config_server/service/manager/config.go       |   54 -
 config_server/service/manager/flag/request.go |   60 -
 .../service/manager/flag/response.go          |  100 -
 config_server/service/repository/config.go    |   44 -
 config_server/service/test/common_test.go     |   20 -
 config_server/{ => v1}/protocol/README.md     |    0
 .../{ => v1}/protocol/v1/agent.proto          |    0
 config_server/{ => v1}/protocol/v1/user.proto |    0
 config_server/v1/protocol/v2/README.md        |  251 ++
 .../protocol/v2/agentV2.proto}                |   32 +-
 config_server/v1/service/.gitignore           |    4 +
 config_server/v1/service/Dockerfile           |   39 +
 config_server/v1/service/common/data_type.go  |   23 +
 .../v1/service/common/http_response.go        |   35 +
 config_server/v1/service/common/json_file.go  |   64 +
 config_server/v1/service/common/queue.go      |   84 +
 config_server/v1/service/example/setting.json |    8 +
 config_server/v1/service/go.mod               |   53 +
 config_server/v1/service/go.sum               |  252 ++
 .../interface/agent/collection_config.go      |   62 +
 .../v1/service/interface/agent/status.go      |   52 +
 .../v1/service/interface/user/agent_group.go  |  229 ++
 .../interface/user/collection_config.go       |  165 +
 .../v1/service/manager/agent/agent_manager.go |   56 +
 .../service/manager/agent/agent_operator.go   |   75 +
 .../service/manager/config/agent_operator.go  |  232 ++
 .../service/manager/config/config_manager.go  |   54 +
 .../service/manager/config/user_operator.go   |  691 ++++
 config_server/v1/service/manager/manager.go   |   39 +
 config_server/v1/service/model/agent.go       |  140 +
 config_server/v1/service/model/agent_group.go |  101 +
 .../v1/service/model/collection_config.go     |   79 +
 config_server/v1/service/model/model_type.go  |   36 +
 config_server/v1/service/proto/agent.pb.go    | 1473 +++++++++
 config_server/v1/service/proto/user.pb.go     | 2856 +++++++++++++++++
 config_server/v1/service/router/router.go     |   68 +
 config_server/v1/service/service.go           |   25 +
 .../v1/service/setting/mysql-setting.json     |   11 +
 config_server/v1/service/setting/setting.go   |  104 +
 config_server/v1/service/setting/setting.json |    8 +
 .../v1/service/setting/sqlite-setting.json    |   10 +
 config_server/v1/service/store/gorm/gorm.go   |  273 ++
 .../interface_database/interface_database.go  |   80 +
 .../v1/service/store/leveldb/leveldb.go       |  221 ++
 config_server/v1/service/store/store.go       |   63 +
 .../v1/service/test/interface_test.go         | 1231 +++++++
 config_server/v1/service/test/request.go      |  323 ++
 .../v1/service/test/setting/setting.json      |    1 +
 config_server/v1/service/test/setting_test.go |   37 +
 config_server/v1/service/test/store_test.go   |   68 +
 config_server/{ => v1}/ui/README.md           |    0
 config_server/v2/README.md                    |   12 +
 config_server/v2/protocol/README.md           |    7 +
 config_server/v2/protocol/v1/agent.proto      |  134 +
 config_server/v2/protocol/v1/user.proto       |  234 ++
 config_server/{ => v2}/protocol/v2/README.md  |   10 +-
 config_server/v2/protocol/v2/agent.proto      |  168 +
 config_server/v2/protocol/v2/user.proto       |  221 ++
 config_server/{ => v2}/service/.gitignore     |    0
 config_server/{ => v2}/service/Dockerfile     |    0
 config_server/{ => v2}/service/Dockerfile-dev |    0
 config_server/{ => v2}/service/README.md      |    0
 .../cmd/config/prod/databaseConfig.json       |    0
 .../service/cmd/config/prod/serverConfig.json |    0
 config_server/{ => v2}/service/cmd/main.go    |    0
 .../{ => v2}/service/common/api_error.go      |    0
 .../{ => v2}/service/common/http_status.go    |    0
 config_server/{ => v2}/service/common/log.go  |    0
 .../{ => v2}/service/common/result.go         |    0
 config_server/{ => v2}/service/config/gorm.go |    0
 .../{ => v2}/service/config/server.go         |    0
 .../{ => v2}/service/entity/agent.go          |    0
 .../{ => v2}/service/entity/agent_group.go    |    0
 config_server/{ => v2}/service/entity/base.go |    0
 .../{ => v2}/service/entity/command.go        |    0
 .../service/entity/instance_config.go         |    0
 .../service/entity/pipeline_config.go         |    0
 config_server/{ => v2}/service/go.mod         |    4 +
 config_server/{ => v2}/service/go.sum         |   12 +-
 .../{ => v2}/service/handler/agent.go         |    0
 .../{ => v2}/service/handler/agent_group.go   |    0
 .../{ => v2}/service/handler/common.go        |    4 +-
 .../service/handler/instance_config.go        |    0
 .../service/handler/pipeline_config.go        |    0
 .../{ => v2}/service/manager/agent.go         |    0
 .../{ => v2}/service/manager/agent_group.go   |    0
 .../service/manager/instance_config.go        |    0
 .../service/manager/pipeline_config.go        |    0
 .../{ => v2}/service/manager/state/agent.go   |    0
 .../{ => v2}/service/manager/state/common.go  |    0
 .../{ => v2}/service/manager/state/request.go |    0
 .../service/manager/state/response.go         |    0
 .../{ => v2}/service/manager/state/server.go  |    0
 .../{ => v2}/service/protov2/README.md        |    0
 .../{ => v2}/service/protov2/agent.pb.go      |    0
 .../{ => v2}/service/protov2/user.pb.go       |    0
 .../{ => v2}/service/repository/agent.go      |    0
 .../service/repository/agent_group.go         |    0
 .../{ => v2}/service/repository/base.go       |    0
 .../service/repository/instance_config.go     |    0
 .../service/repository/pipeline_config.go     |    0
 .../{ => v2}/service/router/router.go         |    0
 .../{ => v2}/service/service/agent.go         |    0
 .../{ => v2}/service/service/agent_group.go   |    2 +-
 .../service/service/instance_config.go        |    5 +-
 .../service/service/pipeline_config.go        |    4 +-
 config_server/{ => v2}/service/store/gorm.go  |    0
 .../{ => v2}/service/store/gorm_test.go       |    0
 config_server/{ => v2}/service/store/store.go |    0
 config_server/v2/service/test/api_test.go     |  581 ++++
 .../test/cmd/config/dev/databaseConfig.json   |    9 +
 .../test/cmd/config/dev/serverConfig.json     |   14 +
 config_server/v2/service/test/common_test.go  |   10 +
 .../v2/service/test/request/agent.go          |   20 +
 .../v2/service/test/request/agent_group.go    |   34 +
 .../service/test/request/common.go}           |   36 +-
 .../service/test/request/instance_config.go   |    1 +
 .../service/test/request/pipeline_config.go   |  119 +
 config_server/v2/service/test/store_test.go   |    1 +
 .../{ => v2}/service/utils/environment.go     |    0
 config_server/{ => v2}/service/utils/json.go  |    0
 config_server/{ => v2}/service/utils/list.go  |    0
 config_server/{ => v2}/service/utils/str.go   |    0
 config_server/{ => v2}/service/utils/task.go  |    0
 130 files changed, 11292 insertions(+), 718 deletions(-)
 delete mode 100644 config_server/service/cmd/env.json
 delete mode 100644 config_server/service/entity/agent_and_config.go
 delete mode 100644 config_server/service/entity/config.go
 delete mode 100644 config_server/service/manager/capability/agent.go
 delete mode 100644 config_server/service/manager/capability/common.go
 delete mode 100644 config_server/service/manager/capability/server.go
 delete mode 100644 config_server/service/manager/config.go
 delete mode 100644 config_server/service/manager/flag/request.go
 delete mode 100644 config_server/service/manager/flag/response.go
 delete mode 100644 config_server/service/repository/config.go
 delete mode 100644 config_server/service/test/common_test.go
 rename config_server/{ => v1}/protocol/README.md (100%)
 rename config_server/{ => v1}/protocol/v1/agent.proto (100%)
 rename config_server/{ => v1}/protocol/v1/user.proto (100%)
 create mode 100644 config_server/v1/protocol/v2/README.md
 rename config_server/{protocol/v2/agent.proto => v1/protocol/v2/agentV2.proto} (89%)
 create mode 100644 config_server/v1/service/.gitignore
 create mode 100644 config_server/v1/service/Dockerfile
 create mode 100644 config_server/v1/service/common/data_type.go
 create mode 100644 config_server/v1/service/common/http_response.go
 create mode 100644 config_server/v1/service/common/json_file.go
 create mode 100644 config_server/v1/service/common/queue.go
 create mode 100644 config_server/v1/service/example/setting.json
 create mode 100644 config_server/v1/service/go.mod
 create mode 100644 config_server/v1/service/go.sum
 create mode 100644 config_server/v1/service/interface/agent/collection_config.go
 create mode 100644 config_server/v1/service/interface/agent/status.go
 create mode 100644 config_server/v1/service/interface/user/agent_group.go
 create mode 100644 config_server/v1/service/interface/user/collection_config.go
 create mode 100644 config_server/v1/service/manager/agent/agent_manager.go
 create mode 100644 config_server/v1/service/manager/agent/agent_operator.go
 create mode 100644 config_server/v1/service/manager/config/agent_operator.go
 create mode 100644 config_server/v1/service/manager/config/config_manager.go
 create mode 100644 config_server/v1/service/manager/config/user_operator.go
 create mode 100644 config_server/v1/service/manager/manager.go
 create mode 100644 config_server/v1/service/model/agent.go
 create mode 100644 config_server/v1/service/model/agent_group.go
 create mode 100644 config_server/v1/service/model/collection_config.go
 create mode 100644 config_server/v1/service/model/model_type.go
 create mode 100644 config_server/v1/service/proto/agent.pb.go
 create mode 100644 config_server/v1/service/proto/user.pb.go
 create mode 100644 config_server/v1/service/router/router.go
 create mode 100644 config_server/v1/service/service.go
 create mode 100644 config_server/v1/service/setting/mysql-setting.json
 create mode 100644 config_server/v1/service/setting/setting.go
 create mode 100644 config_server/v1/service/setting/setting.json
 create mode 100644 config_server/v1/service/setting/sqlite-setting.json
 create mode 100644 config_server/v1/service/store/gorm/gorm.go
 create mode 100644 config_server/v1/service/store/interface_database/interface_database.go
 create mode 100644 config_server/v1/service/store/leveldb/leveldb.go
 create mode 100644 config_server/v1/service/store/store.go
 create mode 100644 config_server/v1/service/test/interface_test.go
 create mode 100644 config_server/v1/service/test/request.go
 create mode 100644 config_server/v1/service/test/setting/setting.json
 create mode 100644 config_server/v1/service/test/setting_test.go
 create mode 100644 config_server/v1/service/test/store_test.go
 rename config_server/{ => v1}/ui/README.md (100%)
 create mode 100644 config_server/v2/README.md
 create mode 100644 config_server/v2/protocol/README.md
 create mode 100644 config_server/v2/protocol/v1/agent.proto
 create mode 100644 config_server/v2/protocol/v1/user.proto
 rename config_server/{ => v2}/protocol/v2/README.md (97%)
 create mode 100644 config_server/v2/protocol/v2/agent.proto
 create mode 100644 config_server/v2/protocol/v2/user.proto
 rename config_server/{ => v2}/service/.gitignore (100%)
 rename config_server/{ => v2}/service/Dockerfile (100%)
 rename config_server/{ => v2}/service/Dockerfile-dev (100%)
 rename config_server/{ => v2}/service/README.md (100%)
 rename config_server/{ => v2}/service/cmd/config/prod/databaseConfig.json (100%)
 rename config_server/{ => v2}/service/cmd/config/prod/serverConfig.json (100%)
 rename config_server/{ => v2}/service/cmd/main.go (100%)
 rename config_server/{ => v2}/service/common/api_error.go (100%)
 rename config_server/{ => v2}/service/common/http_status.go (100%)
 rename config_server/{ => v2}/service/common/log.go (100%)
 rename config_server/{ => v2}/service/common/result.go (100%)
 rename config_server/{ => v2}/service/config/gorm.go (100%)
 rename config_server/{ => v2}/service/config/server.go (100%)
 rename config_server/{ => v2}/service/entity/agent.go (100%)
 rename config_server/{ => v2}/service/entity/agent_group.go (100%)
 rename config_server/{ => v2}/service/entity/base.go (100%)
 rename config_server/{ => v2}/service/entity/command.go (100%)
 rename config_server/{ => v2}/service/entity/instance_config.go (100%)
 rename config_server/{ => v2}/service/entity/pipeline_config.go (100%)
 rename config_server/{ => v2}/service/go.mod (91%)
 rename config_server/{ => v2}/service/go.sum (95%)
 rename config_server/{ => v2}/service/handler/agent.go (100%)
 rename config_server/{ => v2}/service/handler/agent_group.go (100%)
 rename config_server/{ => v2}/service/handler/common.go (90%)
 rename config_server/{ => v2}/service/handler/instance_config.go (100%)
 rename config_server/{ => v2}/service/handler/pipeline_config.go (100%)
 rename config_server/{ => v2}/service/manager/agent.go (100%)
 rename config_server/{ => v2}/service/manager/agent_group.go (100%)
 rename config_server/{ => v2}/service/manager/instance_config.go (100%)
 rename config_server/{ => v2}/service/manager/pipeline_config.go (100%)
 rename config_server/{ => v2}/service/manager/state/agent.go (100%)
 rename config_server/{ => v2}/service/manager/state/common.go (100%)
 rename config_server/{ => v2}/service/manager/state/request.go (100%)
 rename config_server/{ => v2}/service/manager/state/response.go (100%)
 rename config_server/{ => v2}/service/manager/state/server.go (100%)
 rename config_server/{ => v2}/service/protov2/README.md (100%)
 rename config_server/{ => v2}/service/protov2/agent.pb.go (100%)
 rename config_server/{ => v2}/service/protov2/user.pb.go (100%)
 rename config_server/{ => v2}/service/repository/agent.go (100%)
 rename config_server/{ => v2}/service/repository/agent_group.go (100%)
 rename config_server/{ => v2}/service/repository/base.go (100%)
 rename config_server/{ => v2}/service/repository/instance_config.go (100%)
 rename config_server/{ => v2}/service/repository/pipeline_config.go (100%)
 rename config_server/{ => v2}/service/router/router.go (100%)
 rename config_server/{ => v2}/service/service/agent.go (100%)
 rename config_server/{ => v2}/service/service/agent_group.go (96%)
 rename config_server/{ => v2}/service/service/instance_config.go (98%)
 rename config_server/{ => v2}/service/service/pipeline_config.go (98%)
 rename config_server/{ => v2}/service/store/gorm.go (100%)
 rename config_server/{ => v2}/service/store/gorm_test.go (100%)
 rename config_server/{ => v2}/service/store/store.go (100%)
 create mode 100644 config_server/v2/service/test/api_test.go
 create mode 100644 config_server/v2/service/test/cmd/config/dev/databaseConfig.json
 create mode 100644 config_server/v2/service/test/cmd/config/dev/serverConfig.json
 create mode 100644 config_server/v2/service/test/common_test.go
 create mode 100644 config_server/v2/service/test/request/agent.go
 create mode 100644 config_server/v2/service/test/request/agent_group.go
 rename config_server/{service/router/router_test.go => v2/service/test/request/common.go} (56%)
 create mode 100644 config_server/v2/service/test/request/instance_config.go
 create mode 100644 config_server/v2/service/test/request/pipeline_config.go
 create mode 100644 config_server/v2/service/test/store_test.go
 rename config_server/{ => v2}/service/utils/environment.go (100%)
 rename config_server/{ => v2}/service/utils/json.go (100%)
 rename config_server/{ => v2}/service/utils/list.go (100%)
 rename config_server/{ => v2}/service/utils/str.go (100%)
 rename config_server/{ => v2}/service/utils/task.go (100%)

diff --git a/config_server/service/cmd/env.json b/config_server/service/cmd/env.json
deleted file mode 100644
index 866050d02b..0000000000
--- a/config_server/service/cmd/env.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  "env": "prod"
-}
\ No newline at end of file
diff --git a/config_server/service/entity/agent_and_config.go b/config_server/service/entity/agent_and_config.go
deleted file mode 100644
index db9c3e2971..0000000000
--- a/config_server/service/entity/agent_and_config.go
+++ /dev/null
@@ -1,81 +0,0 @@
-package entity
-
-import (
-	proto "config-server/protov2"
-)
-
-type AgentPipelineConfig struct {
-	AgentInstanceId    string `gorm:"primarykey"`
-	PipelineConfigName string `gorm:"primarykey"`
-	Status             ConfigStatus
-	Message            string
-}
-
-func (apc AgentPipelineConfig) TableName() string {
-	return agentPipelineConfigTable
-}
-
-func ParseProtoConfigInfo2AgentPipelineConfig(instanceId string, c *proto.ConfigInfo) *AgentPipelineConfig {
-	return &AgentPipelineConfig{
-		AgentInstanceId:    instanceId,
-		PipelineConfigName: c.Name,
-		Status:             ConfigStatus(c.Status),
-		Message:            c.Message,
-	}
-}
-
-func (apc AgentPipelineConfig) Equals(obj any) bool {
-	if a1, ok := obj.(AgentPipelineConfig); ok {
-		return apc.AgentInstanceId == a1.AgentInstanceId && apc.PipelineConfigName == a1.PipelineConfigName
-	}
-	if a1, ok := obj.(*AgentPipelineConfig); ok {
-		return apc.AgentInstanceId == a1.AgentInstanceId && apc.PipelineConfigName == a1.PipelineConfigName
-	}
-	return false
-}
-
-func (apc AgentPipelineConfig) Parse2ProtoAgentConfigStatus() *proto.AgentConfigStatus {
-	return &proto.AgentConfigStatus{
-		Name:    apc.PipelineConfigName,
-		Status:  proto.ConfigStatus(apc.Status),
-		Message: apc.Message,
-	}
-}
-
-type AgentInstanceConfig struct {
-	AgentInstanceId    string `gorm:"primarykey"`
-	InstanceConfigName string `gorm:"primarykey"`
-	Status             ConfigStatus
-	Message            string
-}
-
-func (aic AgentInstanceConfig) TableName() string {
-	return agentInstanceConfigTable
-}
-
-func ParseProtoConfigInfo2AgentInstanceConfig(instanceId string, c *proto.ConfigInfo) *AgentInstanceConfig {
-	return &AgentInstanceConfig{
-		AgentInstanceId:    instanceId,
-		InstanceConfigName: c.Name,
-		Status:             ConfigStatus(c.Status),
-		Message:            c.Message,
-	}
-}
-
-func (aic AgentInstanceConfig) Parse2ProtoAgentConfigStatus() *proto.AgentConfigStatus {
-	return &proto.AgentConfigStatus{
-		Name:    aic.InstanceConfigName,
-		Status:  proto.ConfigStatus(aic.Status),
-		Message: aic.Message,
-	}
-}
-
-func (aic AgentInstanceConfig) Equals(obj any) bool {
-	if a1, ok := obj.(AgentInstanceConfig); ok {
-		return aic.AgentInstanceId == a1.AgentInstanceId && aic.InstanceConfigName == a1.InstanceConfigName
-	}
-	if a1, ok := obj.(*AgentInstanceConfig); ok {
-		return aic.AgentInstanceId == a1.AgentInstanceId && aic.InstanceConfigName == a1.InstanceConfigName
-	}
-	return false
-}
diff --git a/config_server/service/entity/config.go b/config_server/service/entity/config.go
deleted file mode 100644
index 9c506ddfab..0000000000
--- a/config_server/service/entity/config.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package entity
-
-import (
-	proto "config-server/protov2"
-)
-
-type ConfigStatus int32
-
-type PipelineConfig struct {
-	Name        string `gorm:"primarykey"`
-	Version     int64
-	Detail      []byte
-	Agents      []*Agent      `gorm:"many2many:agent_pipeline_config;foreignKey:Name;joinForeignKey:PipelineConfigName;References:InstanceId;joinReferences:AgentInstanceId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
-	AgentGroups []*AgentGroup `gorm:"many2many:agent_group_pipeline_config;foreignKey:Name;joinForeignKey:PipelineConfigName;References:Name;joinReferences:AgentGroupName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
-}
-
-func (PipelineConfig) TableName() string {
-	return pipelineConfigTable
-}
-
-func (c PipelineConfig) Parse2ProtoPipelineConfigDetail(isContainDetail bool) *proto.ConfigDetail {
-	if isContainDetail {
-		return &proto.ConfigDetail{
-			Name:    c.Name,
-			Version: c.Version,
-			Detail:  c.Detail,
-		}
-	}
-	return &proto.ConfigDetail{
-		Name:    c.Name,
-		Version: c.Version,
-	}
-}
-
-func ParseProtoPipelineConfig2PipelineConfig(c *proto.ConfigDetail) *PipelineConfig {
-	return &PipelineConfig{
-		Name:    c.Name,
-		Version: c.Version,
-		Detail:  c.Detail,
-	}
-}
-
-type InstanceConfig struct {
-	Name        string `gorm:"primarykey"`
-	Version     int64
-	Detail      []byte
-	Agents      []*Agent      `gorm:"many2many:agent_instance_config;foreignKey:Name;joinForeignKey:InstanceConfigName;References:InstanceId;joinReferences:AgentInstanceId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
-	AgentGroups []*AgentGroup `gorm:"many2many:agent_group_instance_config;foreignKey:Name;joinForeignKey:InstanceConfigName;References:Name;joinReferences:AgentGroupName;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
-}
-
-func (c InstanceConfig) Parse2ProtoInstanceConfigDetail(isContainDetail bool) *proto.ConfigDetail {
-	if isContainDetail {
-		return &proto.ConfigDetail{
-			Name:    c.Name,
-			Version: c.Version,
-			Detail:  c.Detail,
-		}
-	}
-	return &proto.ConfigDetail{
-		Name:    c.Name,
-		Version: c.Version,
-	}
-}
-
-func ParseProtoInstanceConfig2InstanceConfig(c *proto.ConfigDetail) *InstanceConfig {
-	return &InstanceConfig{
-		Name:    c.Name,
-		Version: c.Version,
-		Detail:  c.Detail,
-	}
-}
-
-func (InstanceConfig) TableName() string {
-	return instanceConfigTable
-}
diff --git a/config_server/service/manager/capability/agent.go b/config_server/service/manager/capability/agent.go
deleted file mode 100644
index 575e5ff97b..0000000000
--- a/config_server/service/manager/capability/agent.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package capability
-
-import (
-	"config-server/common"
-	"config-server/manager"
-	proto "config-server/protov2"
-	"log"
-)
-
-type AgentAction struct {
-	Base
-	run func(*proto.HeartbeatRequest, *proto.HeartbeatResponse, ...any) error
-}
-
-func (a AgentAction) Action(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse, arg ...any) error {
-	code := a.Code
-	if int(req.Capabilities)&code == code {
-		err := a.run(req, res, arg...)
-		return common.SystemError(err)
-	}
-	return nil
-}
-
-var (
-	AgentUnSpecifiedAction = &AgentAction{
-		Base: AgentUnSpecified,
-		run:  UnspecifiedRun,
-	}
-	AcceptsPipelineConfigAction = &AgentAction{
-		Base: AcceptsPipelineConfig,
-		run:  AcceptsPipelineConfigRun,
-	}
-	AcceptsInstanceConfigAction = AgentAction{
-		Base: AcceptsInstanceConfig,
-		run:  AcceptsInstanceConfigRun,
-	}
-	AcceptsCustomCommandAction = &AgentAction{
-		Base: AcceptsCustomCommand,
-		run:  AcceptsCustomCommandRun,
-	}
-)
-
-//agent有接收某种配置的能力,则响应中设置对应的配置
-
-func UnspecifiedRun(*proto.HeartbeatRequest, *proto.HeartbeatResponse, ...any) error {
-	return nil
-}
-
-// AcceptsPipelineConfigRun 返回PipelineConfigDetail
-func AcceptsPipelineConfigRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse, arg ...any) error {
-	if arg == nil || len(arg) == 0 {
-		return common.ServerErrorWithMsg("The arg parameter cannot be null")
-	}
-
-	if isContainDetail, ok := arg[0].(bool); ok {
-		strInstanceId := string(req.InstanceId)
-		pipelineConfigUpdates, err := manager.GetPipelineConfigs(strInstanceId, isContainDetail)
-		if err != nil {
-			return common.SystemError(err)
-		}
-		res.PipelineConfigUpdates = pipelineConfigUpdates
-		return nil
-	}
-	return common.ServerErrorWithMsg("Arg is illegal, what is required is a boolean type parameter")
-}
-
-// AcceptsInstanceConfigRun 返回InstanceConfigDetail
-func AcceptsInstanceConfigRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse, arg ...any) error {
-	if arg == nil || len(arg) == 0 {
-		return common.ServerErrorWithMsg("The arg parameter cannot be null")
-	}
-
-	if isContainDetail, ok := arg[0].(bool); ok {
-		strInstanceId := string(req.InstanceId)
-		instanceConfigUpdates, err := manager.GetInstanceConfigs(strInstanceId, isContainDetail)
-		if err != nil {
-			return common.SystemError(err)
-		}
-		res.InstanceConfigUpdates = instanceConfigUpdates
-		return nil
-	}
-	return common.ServerErrorWithMsg("Arg is illegal, what is required is a boolean type parameter")
-}
-
-func AcceptsCustomCommandRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse, arg ...any) error {
-	log.Print("command capability action run ...")
-	return nil
-}
diff --git a/config_server/service/manager/capability/common.go b/config_server/service/manager/capability/common.go
deleted file mode 100644
index 7ec3ff94a2..0000000000
--- a/config_server/service/manager/capability/common.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package capability
-
-type Base struct {
-	Code  int
-	Value string
-}
-
-// server
-var (
-	ServerUnspecified            = Base{0, "unspecified"}
-	RememberAttribute            = Base{1, "rememberAttribute"}
-	RememberPipelineConfigStatus = Base{2, "rememberPipelineConfigStatus"}
-	RememberInstanceConfigStatus = Base{4, "rememberInstanceConfigStatus"}
-	RememberCustomCommandStatus  = Base{8, "rememberCustomCommandStatus"}
-)
-
-// agent
-var (
-	AgentUnSpecified      = Base{0, "unspecified"}
-	AcceptsPipelineConfig = Base{1, "acceptsPipelineConfig"}
-	AcceptsInstanceConfig = Base{2, "acceptsInstanceConfig"}
-	AcceptsCustomCommand  = Base{4, "acceptsCustomCommand"}
-)
diff --git a/config_server/service/manager/capability/server.go b/config_server/service/manager/capability/server.go
deleted file mode 100644
index c2d6b1e30b..0000000000
--- a/config_server/service/manager/capability/server.go
+++ /dev/null
@@ -1,112 +0,0 @@
-package capability
-
-import (
-	"config-server/common"
-	"config-server/config"
-	"config-server/entity"
-	"config-server/manager"
-	proto "config-server/protov2"
-	"config-server/repository"
-)
-
-type ServerAction struct {
-	Base
-	run func(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error
-}
-
-func (a ServerAction) Action(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	serverCapabilityType := a.Value
-	hasServerCapability, ok := config.ServerConfigInstance.Capabilities[serverCapabilityType]
-	if !ok {
-		return common.ServerErrorWithMsg("error serverCapability type(%s)", serverCapabilityType)
-	}
-
-	if hasServerCapability {
-		err := a.run(req, res)
-		return common.SystemError(err)
-	}
-	return nil
-}
-
-func (a ServerAction) UpdateCapabilities(res *proto.HeartbeatResponse) {
-	res.Capabilities = res.Capabilities | uint64(a.Code)
-}
-
-var (
-	UnspecifiedServerAction = &ServerAction{
-		Base: ServerUnspecified,
-		run:  UnspecifiedServerCapabilityRun,
-	}
-
-	RememberAttributeAction = &ServerAction{
-		Base: RememberAttribute,
-		run:  RememberAttributeCapabilityRun,
-	}
-	RememberPipelineConfigStatusAction = &ServerAction{
-		Base: RememberPipelineConfigStatus,
-		run:  RememberPipelineConfigStatusCapabilityRun,
-	}
-	RememberInstanceConfigStatusAction = &ServerAction{
-		Base: RememberInstanceConfigStatus,
-		run:  RememberInstanceConfigStatusCapabilityRun,
-	}
-	RememberCustomCommandStatusAction = &ServerAction{
-		Base: RememberCustomCommandStatus,
-		run:  RememberCustomCommandStatusRun,
-	}
-)
-
-var ServerActionList = []*ServerAction{
-	UnspecifiedServerAction,
-	RememberAttributeAction,
-	RememberPipelineConfigStatusAction,
-	RememberInstanceConfigStatusAction,
-	RememberCustomCommandStatusAction,
-}
-
-func UnspecifiedServerCapabilityRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	return nil
-}
-
-func RememberAttributeCapabilityRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	attributes := req.Attributes
-	if attributes == nil {
-		return nil
-	}
-	agent := &entity.Agent{}
-	agent.Attributes = entity.ParseProtoAgentAttributes2AgentAttributes(attributes)
-	err := repository.UpdateAgentById(agent, "attributes")
-	return common.SystemError(err)
-}
-
-func RememberPipelineConfigStatusCapabilityRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	configs := req.PipelineConfigs
-	if configs == nil {
-		return nil
-	}
-	agentPipelineConfigs := make([]*entity.AgentPipelineConfig, 0)
-	for _, reqPipelineConfig := range req.PipelineConfigs {
-		agentPipelineConfig := entity.ParseProtoConfigInfo2AgentPipelineConfig(string(req.InstanceId), reqPipelineConfig)
-		agentPipelineConfigs = append(agentPipelineConfigs, agentPipelineConfig)
-	}
-	err := manager.CreateOrUpdateAgentPipelineConfigs(agentPipelineConfigs)
-	return common.SystemError(err)
-}
-
-func RememberInstanceConfigStatusCapabilityRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	configs := req.InstanceConfigs
-	if configs == nil {
-		return nil
-	}
-	agentInstanceConfigs := make([]*entity.AgentInstanceConfig, 0)
-	for _, reqInstanceConfig := range req.InstanceConfigs {
-		agentInstanceConfig := entity.ParseProtoConfigInfo2AgentInstanceConfig(string(req.InstanceId), reqInstanceConfig)
-		agentInstanceConfigs = append(agentInstanceConfigs, agentInstanceConfig)
-	}
-	err := manager.CreateOrUpdateAgentInstanceConfigs(agentInstanceConfigs)
-	return common.SystemError(err)
-}
-
-func RememberCustomCommandStatusRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	return nil
-}
diff --git a/config_server/service/manager/config.go b/config_server/service/manager/config.go
deleted file mode 100644
index 05f2db9f65..0000000000
--- a/config_server/service/manager/config.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package manager
-
-import (
-	"config-server/common"
-	"config-server/entity"
-	proto "config-server/protov2"
-	"config-server/repository"
-)
-
-func CreateOrUpdateAgentInstanceConfigs(agentInstanceConfigs []*entity.AgentInstanceConfig) error {
-	conflictColumnNames := []string{"agent_instance_id", "instance_config_name"}
-	assignmentColumnNames := []string{"status", "message"}
-	err := repository.CreateOrUpdateAgentInstanceConfigs(conflictColumnNames, assignmentColumnNames, agentInstanceConfigs...)
-	return common.SystemError(err)
-}
-
-func CreateOrUpdateAgentPipelineConfigs(agentPipelineConfigs []*entity.AgentPipelineConfig) error {
-	conflictColumnNames := []string{"agent_instance_id", "pipeline_config_name"}
-	assignmentColumnNames := []string{"status", "message"}
-	err := repository.CreateOrUpdateAgentPipelineConfigs(conflictColumnNames, assignmentColumnNames, agentPipelineConfigs...)
-	return common.SystemError(err)
-}
-
-func GetPipelineConfigs(instanceId string, isContainDetail bool) ([]*proto.ConfigDetail, error) {
-	var err error
-	agent := &entity.Agent{InstanceId: instanceId}
-	err = repository.GetPipelineConfigsByAgent(agent)
-	if err != nil {
-		return nil, err
-	}
-
-	pipelineConfigUpdates := make([]*proto.ConfigDetail, 0)
-	for _, config := range agent.PipelineConfigs {
-		detail := config.Parse2ProtoPipelineConfigDetail(isContainDetail)
-		pipelineConfigUpdates = append(pipelineConfigUpdates, detail)
-	}
-	return pipelineConfigUpdates, nil
-}
-
-func GetInstanceConfigs(instanceId string, isContainDetail bool) ([]*proto.ConfigDetail, error) {
-	var err error
-	agent := &entity.Agent{InstanceId: instanceId}
-	err = repository.GetInstanceConfigsByAgent(agent)
-	if err != nil {
-		return nil, err
-	}
-
-	instanceConfigUpdates := make([]*proto.ConfigDetail, 0)
-	for _, config := range agent.InstanceConfigs {
-		detail := config.Parse2ProtoInstanceConfigDetail(isContainDetail)
-		instanceConfigUpdates = append(instanceConfigUpdates, detail)
-	}
-	return instanceConfigUpdates, err
-}
diff --git a/config_server/service/manager/flag/request.go b/config_server/service/manager/flag/request.go
deleted file mode 100644
index 9ed758338e..0000000000
--- a/config_server/service/manager/flag/request.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package flag
-
-import (
-	"config-server/common"
-	"config-server/manager/capability"
-	proto "config-server/protov2"
-)
-
-const (
-	RequestUnspecified     = "unspecified"
-	RequestReportFullState = "reportFullState"
-)
-
-type RequestAction struct {
-	Value string
-	Run   func(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error
-}
-
-var RequestMap = map[int]*RequestAction{
-	0: {
-		Value: RequestUnspecified,
-		Run:   RequestUnspecifiedRun,
-	},
-	1: {
-		Value: RequestReportFullState,
-		Run:   RequestReportFullStateRun,
-	},
-}
-
-// RequestUnspecifiedRun agent上报简单信息
-func RequestUnspecifiedRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	for _, action := range capability.ServerActionList {
-		action.UpdateCapabilities(res)
-	}
-	return nil
-}
-
-// RequestReportFullStateRun agent上传全量信息
-func RequestReportFullStateRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	for _, action := range capability.ServerActionList {
-		action.UpdateCapabilities(res)
-		err := action.Action(req, res)
-		if err != nil {
-			return common.SystemError(err)
-		}
-	}
-	return nil
-}
-
-func HandleRequestFlags(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	for key, value := range RequestMap {
-		if int(req.Flags)&key == key {
-			err := value.Run(req, res)
-			if err != nil {
-				return common.SystemError(err)
-			}
-		}
-	}
-	return nil
-}
diff --git a/config_server/service/manager/flag/response.go b/config_server/service/manager/flag/response.go
deleted file mode 100644
index aaa4d7bf6a..0000000000
--- a/config_server/service/manager/flag/response.go
+++ /dev/null
@@ -1,100 +0,0 @@
-package flag
-
-import (
-	"config-server/common"
-	"config-server/config"
-	"config-server/manager/capability"
-	proto "config-server/protov2"
-)
-
-type ResponseAction struct {
-	Code int
-	Run1 func(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error
-	Run2 func(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error
-}
-
-const (
-	Unspecified               = "unspecified"
-	ReportFullState           = "reportFullState"
-	FetchPipelineConfigDetail = "fetchPipelineConfigDetail"
-	FetchInstanceConfigDetail = "fetchInstanceConfigDetail"
-)
-
-var ResponseMap = map[string]*ResponseAction{
-	Unspecified: {
-		Code: 0,
-		Run1: ResponseUnspecifiedRun,
-	},
-	ReportFullState: {
-		Code: 1,
-		Run1: ResponseReportFullStateRun,
-	},
-	FetchPipelineConfigDetail: {
-		Code: 2,
-		Run1: FetchPipelineConfigDetailRun,
-		Run2: FetchPipelineConfigDetailIncludeDetailRun,
-	},
-	FetchInstanceConfigDetail: {
-		Code: 4,
-		Run1: FetchInstanceConfigDetailRun,
-		Run2: FetchInstanceConfigDetailIncludeDetailRun,
-	},
-}
-
-func ResponseUnspecifiedRun(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error {
-	return nil
-}
-
-func ResponseReportFullStateRun(*proto.HeartbeatRequest, *proto.HeartbeatResponse) error {
-	return nil
-}
-
-func FetchPipelineConfigDetailIncludeDetailRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	err := capability.AcceptsPipelineConfigAction.Action(req, res, true)
-	return common.SystemError(err)
-}
-
-// FetchPipelineConfigDetailRun 要求agent做的事情,比如配置不发送pipelineConfig的Detail,
-// 这里就要求它主动请求FetchPipelineConfig接口(只需改变res.flags并且configUpdate不包含detail)
-func FetchPipelineConfigDetailRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	err := capability.AcceptsPipelineConfigAction.Action(req, res, false)
-	return common.SystemError(err)
-}
-
-func FetchInstanceConfigDetailRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	err := capability.AcceptsInstanceConfigAction.Action(req, res, false)
-	return common.SystemError(err)
-}
-
-func FetchInstanceConfigDetailIncludeDetailRun(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	err := capability.AcceptsInstanceConfigAction.Action(req, res, true)
-	return common.SystemError(err)
-}
-
-func HandleResponseFlags(req *proto.HeartbeatRequest, res *proto.HeartbeatResponse) error {
-	for key, value := range config.ServerConfigInstance.ResponseFlags {
-		action, ok := ResponseMap[key]
-		if !ok {
-			panic("not the correct responseFlags config...")
-		}
-		if value {
-			res.Flags = res.Flags | uint64(action.Code)
-			if action.Run1 == nil {
-				continue
-			}
-			err := action.Run1(req, res)
-			if err != nil {
-				return common.SystemError(err)
-			}
-		} else {
-			if action.Run2 == nil {
-				continue
-			}
-			err := action.Run2(req, res)
-			if err != nil {
-				return common.SystemError(err)
-			}
-		}
-	}
-	return nil
-}
diff --git a/config_server/service/repository/config.go b/config_server/service/repository/config.go
deleted file mode 100644
index ab1dc9a12a..0000000000
--- a/config_server/service/repository/config.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package repository
-
-import (
-	"config-server/common"
-	"config-server/entity"
-)
-
-func CreateOrUpdateAgentPipelineConfigs(conflictColumnNames []string, assignmentColumns []string, configs ...*entity.AgentPipelineConfig) error {
-	err := createOrUpdateEntities(conflictColumnNames, assignmentColumns, configs...)
-	return common.SystemError(err)
-}
-
-func CreateOrUpdateAgentInstanceConfigs(conflictColumnNames []string, assignmentColumns []string, configs ...*entity.AgentInstanceConfig) error {
-	err := createOrUpdateEntities(conflictColumnNames, assignmentColumns, configs...)
-	return common.SystemError(err)
-}
-
-func GetPipelineConfigByName(name string) (*entity.PipelineConfig, error) {
-	pipelineConfig := entity.PipelineConfig{}
-	row := s.Db.Where("name=?", name).Find(&pipelineConfig).RowsAffected
-	if row != 1 {
-		return nil, common.ServerErrorWithMsg("pipelineName=%s can not be found", name)
-	}
-	return &pipelineConfig, nil
-}
-
-func GetInstanceConfigByName(name string) (*entity.InstanceConfig, error) {
-	instanceConfig := entity.InstanceConfig{}
-	row := s.Db.Where("name=?", name).Find(&instanceConfig).RowsAffected
-	if row != 1 {
-		return nil, common.ServerErrorWithMsg("instanceName=%s can not be found", name)
-	}
-	return &instanceConfig, nil
-}
-
-func GetPipelineConfigsByAgent(agent *entity.Agent) error {
-	err := s.Db.Preload("PipelineConfigs").Where("instance_id=?", agent.InstanceId).Find(agent).Error
-	return common.SystemError(err)
-}
-
-func GetInstanceConfigsByAgent(agent *entity.Agent) error {
-	err := s.Db.Preload("InstanceConfigs").Where("instance_id=?", agent.InstanceId).Find(agent).Error
-	return common.SystemError(err)
-}
diff --git a/config_server/service/test/common_test.go b/config_server/service/test/common_test.go
deleted file mode 100644
index 2b6b041c6b..0000000000
--- a/config_server/service/test/common_test.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package test
-
-import (
-	"config-server/protov2"
-	"fmt"
-	"google.golang.org/protobuf/proto"
-	"reflect"
-	"testing"
-)
-
-func NewObj[T proto.Message]() {
-	var ptr T
-	fmt.Println(reflect.TypeOf(ptr))
-	fmt.Println(reflect.New(reflect.TypeOf(ptr)).Interface())
-}
-
-func TestProto(t *testing.T) {
-	//NewObj[protov2.CreateAgentGroupRequest]()
-	NewObj[*protov2.CreateAgentGroupRequest]()
-}
diff --git a/config_server/protocol/README.md b/config_server/v1/protocol/README.md
similarity index 100%
rename from config_server/protocol/README.md
rename to config_server/v1/protocol/README.md
diff --git a/config_server/protocol/v1/agent.proto b/config_server/v1/protocol/v1/agent.proto
similarity index 100%
rename from config_server/protocol/v1/agent.proto
rename to config_server/v1/protocol/v1/agent.proto
diff --git a/config_server/protocol/v1/user.proto b/config_server/v1/protocol/v1/user.proto
similarity index 100%
rename from config_server/protocol/v1/user.proto
rename to config_server/v1/protocol/v1/user.proto
diff --git a/config_server/v1/protocol/v2/README.md b/config_server/v1/protocol/v2/README.md
new file mode 100644
index 0000000000..129cc14f40
--- /dev/null
+++ b/config_server/v1/protocol/v2/README.md
@@ -0,0 +1,251 @@
+# 统一管控协议
+
+本规范定义了 Agent 管控网络协议以及 iLogtail 和 ConfigServer 的预期行为。
+
+1. 只要XxxConfigServer实现了协议,那么就可以管控Agent做Yyy事情。
+2. 只要Agent实现了协议,那么任何XxxConfigServer就能过管控该Agent做Yyy事情。
+
+## 管控协议
+
+/Agent/Heartbeat?InstanceId=$instance\_id&WaitForChange=(true|false)
+
+### HeartbeatRequest 消息
+
+    message HeartbeatRequest {
+        bytes request_id = 1;
+        uint64 sequence_num = 2;                    // Increment every request, for server to check sync status
+        uint64 capabilities = 3;                    // Bitmask of flags defined by AgentCapabilities enum
+        bytes instance_id = 4;                      // Required, Agent's unique identification, consistent throughout the process lifecycle
+        string agent_type = 5;                      // Required, Agent's type(ilogtail, ..)
+        AgentAttributes attributes = 6;             // Agent's basic attributes
+        repeated AgentGroupTag tags =  7;           // Agent's tags
+        string running_status = 8;                  // Human readable running status
+        int64 startup_time = 9;                     // Required, Agent's startup time
+        repeated ConfigInfo pipeline_configs = 10;  // Information about the current PIPELINE_CONFIG held by the Agent
+        repeated ConfigInfo instance_configs = 11;   // Information about the current AGENT_CONFIG held by the Agent
+        repeated CommandInfo custom_commands = 12;  // Information about command history
+        uint64 flags = 13;                          // Predefined command flag
+        bytes opaque = 14;                          // Opaque data for extension
+        // before 100 (inclusive) are reserved for future official fields
+    }
+    
+    message AgentGroupTag {
+        string name = 1;
+        string value = 2;
+    }
+
+    enum ConfigStatus {
+        // The value of status field is not set.
+        UNSET = 0;
+        // Agent is currently applying the remote config that it received earlier.
+        APPLYING = 1;
+        // Remote config was successfully applied by the Agent.
+        APPLIED = 2;
+        // Agent tried to apply the config received earlier, but it failed.
+        // See error_message for more details.
+        FAILED = 3;
+    }
+
+    // Define the Config information carried in the request
+    message ConfigInfo {
+        string name = 1;         // Required, Config's unique identification
+        int64 version = 2;       // Required, Config's version number or hash code
+        ConfigStatus status = 3; // Config's status
+    }
+
+    // Define the Command information carried in the request
+    message CommandInfo {
+        string type = 1;         // Command's type
+        string name = 2;         // Required, Command's unique identification
+        ConfigStatus status = 3; // Command's status
+    }
+
+    // Define Agent's basic attributes
+    message AgentAttributes {
+        bytes version = 1;                 // Agent's version
+        bytes ip = 2;                      // Agent's ip
+        bytes hostname = 3;                // Agent's hostname
+        map<string, bytes> extras = 100;   // Agent's other attributes
+        // before 100 (inclusive) are reserved for future official fields
+    }
+
+    enum AgentCapabilities {
+        // The capabilities field is unspecified.
+        UnspecifiedAgentCapability = 0;
+        // The Agent can accept pipeline configuration from the Server.
+        AcceptsPipelineConfig          = 0x00000001;
+        // The Agent can accept instance configuration from the Server.
+        AcceptsInstanceConfig           = 0x00000002;
+        // The Agent can accept custom command from the Server.
+        AcceptsCustomCommand           = 0x00000004;
+
+        // bits before 2^16 (inclusive) are reserved for future official fields
+    }
+
+    enum RequestFlags {
+        RequestFlagsUnspecified = 0;
+
+        // Flags is a bit mask. Values below define individual bits.
+
+        // Must be set if this request contains full state
+        FullState               = 0x00000001;
+        // bits before 2^16 (inclusive) are reserved for future official fields
+    }
+
+### HeartbeatResponse 消息
+
+    message HeartbeatResponse {
+        bytes request_id = 1;  
+        ServerErrorResponse error_response = 2;             // Set value indicates error
+        uint64 capabilities = 3;                            // Bitmask of flags defined by ServerCapabilities enum
+
+        repeated ConfigDetail pipeline_config_updates = 4;  // Agent's pipeline config update status
+        repeated ConfigDetail instance_config_updates = 5;   // Agent's instance config update status
+        repeated CommandDetail custom_command_updates = 6;  // Agent's commands updates
+        uint64 flags = 7;                                   // Predefined command flag
+        bytes opaque = 8;                                   // Opaque data for extension
+    }
+    
+    message ConfigDetail {
+        string name = 1;        // Required, Config's unique identification
+        int64 version = 2;      // Required, Config's version number or hash code
+        bytes detail = 3;       // Required, Config's detail
+    }
+
+    message CommandDetail {
+        string type = 1;                // Required, Command type
+        string name = 2;                // Required, Command name
+        bytes detail = 3;               // Required, Command's detail
+        int64 expire_time = 4;          // After which the command can be safely removed from history
+    }
+
+    enum ServerCapabilities {
+        // The capabilities field is unspecified.
+        UnspecifiedServerCapability = 0;
+        // The Server can remember agent attributes.
+        RembersAttribute                   = 0x00000001;
+        // The Server can remember pipeline config status.
+        RembersPipelineConfigStatus        = 0x00000002;
+        // The Server can remember instance config status.
+        RembersInstanceConfigStatus         = 0x00000004;
+        // The Server can remember custom command status.
+        RembersCustomCommandStatus         = 0x00000008;
+
+        // bits before 2^16 (inclusive) are reserved for future official fields
+    }
+
+    message ServerErrorResponse {
+        int32 error_code = 1;                               // None-zero value indicates error
+        string error_message = 2;                           // Error message
+    }
+
+    enum ResponseFlags {
+        ResponseFlagsUnspecified = 0;
+
+        // Flags is a bit mask. Values below define individual bits.
+
+        // ReportFullState flag can be used by the Server if the Client did not include
+        // some sub-message in the last AgentToServer message (which is an allowed
+        // optimization) but the Server detects that it does not have it (e.g. was
+        // restarted and lost state).
+        ReportFullState           = 0x00000001;
+        FetchPipelineConfigDetail = 0x00000002;
+        FetchInstanceConfigDetail  = 0x00000004;
+        // bits before 2^16 (inclusive) are reserved for future official fields
+    }
+
+## 行为规范
+
+对于管控协议来说 iLogtail 的预期行为是确定性的,对于实现本管控协议的其他 Agent 其具体行为可自行确定,但语义应保持一致。Server 端定义了可选的行为的不同实现,此时对于这些差异 Agent 侧在实现时必须都考虑到且做好兼容。这样,Agent只需要实现一个CommonConfigProvider就可以受任意符合此协议规范的ConfigServer管控。
+
+### 能力报告
+
+Client:应当通过capbilitiies上报Agent自身的能力,这样如果老的客户端接入新的ConfigServer,ConfigServer便知道客户端不具备某项能力,从而不会向其发送不支持的配置或命令而得不到状态汇报导致无限循环。
+
+Server:应当通过capbilitiies上报Server自身的能力,这样如果新的客户端接入老的ConfigServer,Agent便知道服务端不具备某项能力,从而不会被其响应所误导,如其不具备记忆Attributes能力,那么Attributes字段无论如何都不应该在心跳中被省略。
+
+### 注册
+
+Client:Agent启动后第一次向Server汇报全量信息,request字段应填尽填。request\_id、sequence\_num、capabilities、instance\_id、agent\_type、startup\_time为必填字段。
+
+Server:Server根据上报的信息返回响应。pipeline\_config\_updates、instance\_config\_updates中包含agent需要同步的配置,updates中必然包含name和version,是否包含详情context和detail取决于server端实现。custom\_command_updates包含要求agent执行的命令command中必然包含type、name和expire\_time。
+
+Server是否保存Client信息取决于Server实现,如果服务端找不到或保存的sequence\_num + 1 ≠ 心跳的sequence\_num,那么就立刻返回并且flags中必须设置ReportFullStatus标识位。
+
+Server根据agent\_type + attributes 查询进程配置,根据ip和tags查询机器组和关联采集配置。
+
+![image](https://github.com/alibaba/ilogtail/assets/1827594/05799ac2-9249-49ed-8088-3b927821ac73)
+
+### 心跳(心跳压缩)
+
+Client:若接收到的响应中没有ReportFullStatus,且client的属性、配置状态、命令状态在上次上报后没有变化,那么可以只填instance\_id、sequence\_num,sequence\_num每次请求+1。若有ReportStatus或任何属性、配置状态变化或Server不支持属性、配置状态记忆能力,则必须完整上报状态。
+
+Server:同注册
+
+允许心跳压缩
+
+![image](https://github.com/alibaba/ilogtail/assets/1827594/ad22bcfa-b14a-41b5-b4b8-4956bb065bf7)
+
+不允许心跳压缩
+
+![image](https://github.com/alibaba/ilogtail/assets/1827594/35a823fd-6b8e-499f-951e-2231f3319420)
+
+### 进程配置
+
+若Server的注册/心跳响应中有instance\_config\_updates.detail
+
+Client:直接从response中获得detail,应用成功后下次心跳需要上报完整状态。
+
+若Server的响应不包含detail
+
+Client:根据instance\_config\_updates的信息构造FetchInstanceConfigRequest
+
+Server:返回FetchInstanceConfigResponse
+
+Client获取到多个进程配置时,自动合并,若产生冲突默认行为是未定义。
+
+### 采集配置
+
+若Server的注册/心跳响应中有pipeline\_config\_updates.detail
+
+Client:直接从response中获得detail,应用成功后下次心跳需要上报完整状态。
+
+若Server的响应不包含detail
+
+Client:根据pipeline\_config\_updates的信息构造FetchPipelineConfigRequest
+
+Server:返回FetchPipelineConfigResponse
+
+客户端支持以下2种实现
+
+实现1:直接将Detail返回在心跳响应中(FetchConfigDetail flag is unset)
+
+![image](https://github.com/alibaba/ilogtail/assets/1827594/be645615-dd99-42dd-9deb-681e9a4069bb)
+
+实现2:仅返回配置名和版本,Detail使用单独请求获取(FetchConfigDetail flag is set)
+
+![image](https://github.com/alibaba/ilogtail/assets/1827594/c409c35c-2a81-4927-bfd2-7fb321ef1ca8)
+
+### 配置状态上报
+
+Client:这个版本的配置状态上报中修改了version的定义,-1仍然表示删除,0作为保留值,其他值都是合法version,只要version不同Client都应该视为配置更新。此外参考OpAMP增加了配置应用状态上报的字段,能反应出下发的配置是否生效。
+
+Server:这些信息是Agent状态的一部分,可选保存。与通过Event上报可观测信息不同的是,作为状态信息没有时间属性,用户可通过接口可获取即刻状态,而不需要选择时间窗口合并事件。
+
+### 预定义命令
+
+Client: 通过request的flag传递,定义了FullStatus,表明本条信息为全量状态
+
+Server: 通过response的flag传递,定义了ReportFullStatus,表明要求Client上报全量状态信息
+
+### 自定义命令
+
+Client: 为了防止服务端重复下发命令以及感知命令执行结果,在command expire前,Client始终应具备向服务端上报command执行状态的能力,实际是否上报取决于心跳压缩机制。在expire\_time超过后,client不应该再上报超时的command状态。
+
+Server: 如果上报+已知的Agent状态中,缺少应下发的custom\_command\_updates(通过name识别),那么server应该在响应中下发缺少的custom\_command\_updates。
+
+### 异常处理
+
+Server: 服务端正常返回时HeartbeatResponse中的code应始终设置为0,而当服务端异常时,必须将HeartbeatResponse中的code设置为非0,HeartbeatResponse中的message应包含错误信息,此时Response中的其他字段必须为空。
+
+Client: 当HeartbeatResponse中的code为0时,Agent应该正常处理下发的配置。当HeartbeatResponse中的code不为0时,Agent必须忽略除code和message外的其他字段,并择机重试。
diff --git a/config_server/protocol/v2/agent.proto b/config_server/v1/protocol/v2/agentV2.proto
similarity index 89%
rename from config_server/protocol/v2/agent.proto
rename to config_server/v1/protocol/v2/agentV2.proto
index ba53bfcff3..9098bf0d01 100644
--- a/config_server/protocol/v2/agent.proto
+++ b/config_server/v1/protocol/v2/agentV2.proto
@@ -40,6 +40,7 @@ message AgentAttributes {
     bytes version = 1;                 // Agent's version
     bytes ip = 2;                      // Agent's ip
     bytes hostname = 3;                // Agent's hostname
+    bytes hostid = 4;                  // Agent's hostid  https://opentelemetry.io/docs/specs/semconv/attributes-registry/host/
     map<string, bytes> extras = 100;   // Agent's other attributes
     // before 100 (inclusive) are reserved for future official fields
 }
@@ -49,8 +50,8 @@ enum AgentCapabilities {
     UnspecifiedAgentCapability = 0;
     // The Agent can accept pipeline configuration from the Server.
     AcceptsPipelineConfig          = 0x00000001;
-    // The Agent can accept process configuration from the Server.
-    AcceptsProcessConfig           = 0x00000002;
+    // The Agent can accept instance configuration from the Server.
+    AcceptsInstanceConfig           = 0x00000002;
     // The Agent can accept custom command from the Server.
     AcceptsCustomCommand           = 0x00000004;
 
@@ -81,7 +82,7 @@ message HeartbeatRequest {
     string running_status = 8;                  // Human readable running status
     int64 startup_time = 9;                     // Required, Agent's startup time
     repeated ConfigInfo pipeline_configs = 10;  // Information about the current PIPELINE_CONFIG held by the Agent
-    repeated ConfigInfo process_configs = 11;   // Information about the current AGENT_CONFIG held by the Agent
+    repeated ConfigInfo instance_configs = 11;  // Information about the current AGENT_CONFIG held by the Agent
     repeated CommandInfo custom_commands = 12;  // Information about command history
     uint64 flags = 13;                          // Predefined command flag
     bytes opaque = 14;                          // Opaque data for extension
@@ -102,11 +103,6 @@ message CommandDetail {
     int64 expire_time = 4;          // After which the command can be safely removed from history
 }
 
-message ServerErrorResponse {
-    int32 error_code = 1;           // None-zero value indicates error
-    string error_message = 2;       // Error message
-}
-
 enum ServerCapabilities {
     // The capabilities field is unspecified.
     UnspecifiedServerCapability = 0;
@@ -114,8 +110,8 @@ enum ServerCapabilities {
     RembersAttribute                   = 0x00000001;
     // The Server can remember pipeline config status.
     RembersPipelineConfigStatus        = 0x00000002;
-    // The Server can remember process config status.
-    RembersProcessConfigStatus         = 0x00000004;
+    // The Server can remember instance config status.
+    RembersInstanceConfigStatus         = 0x00000004;
     // The Server can remember custom command status.
     RembersCustomCommandStatus         = 0x00000008;
 
@@ -133,25 +129,25 @@ enum ResponseFlags {
     // restarted and lost state).
     ReportFullState           = 0x00000001;
     FetchPipelineConfigDetail = 0x00000002;
-    FetchProcessConfigDetail  = 0x00000004;
+    FetchInstanceConfigDetail = 0x00000004;
     // bits before 2^16 (inclusive) are reserved for future official fields
 }
 
 // ConfigServer's response to Agent's request
 message HeartbeatResponse {
     bytes request_id = 1;  
-    ServerErrorResponse error_response = 2;             // Set value indicates error
+    CommonResponse commonResponse = 2;                  // Set common response
     uint64 capabilities = 3;                            // Bitmask of flags defined by ServerCapabilities enum
 
     repeated ConfigDetail pipeline_config_updates = 4;  // Agent's pipeline config update status
-    repeated ConfigDetail process_config_updates = 5;   // Agent's process config update status
+    repeated ConfigDetail instance_config_updates = 5;  // Agent's instance config update status
     repeated CommandDetail custom_command_updates = 6;  // Agent's commands updates
     uint64 flags = 7;                                   // Predefined command flag
     bytes opaque = 8;                                   // Opaque data for extension
 }
 
 // API: /Agent/FetchPipelineConfig/
-// API: /Agent/FetchProcessConfig/
+// API: /Agent/FetchInstanceConfig/
 // Agent request to ConfigServer, pulling details of the config
 message FetchConfigRequest {
     bytes request_id = 1; 
@@ -162,6 +158,12 @@ message FetchConfigRequest {
 // ConfigServer response to Agent's request
 message FetchConfigResponse {
     bytes request_id = 1;                     
-    ServerErrorResponse error_response = 2;
+    CommonResponse commonResponse = 2;
     repeated ConfigDetail config_details = 3;   // config detail
+}
+
+message CommonResponse
+{
+    int32 status = 1;
+    bytes errorMessage = 2;
 }
\ No newline at end of file
diff --git a/config_server/v1/service/.gitignore b/config_server/v1/service/.gitignore
new file mode 100644
index 0000000000..be5da45682
--- /dev/null
+++ b/config_server/v1/service/.gitignore
@@ -0,0 +1,4 @@
+DB
+ConfigServer
+license.sh
+config-server
diff --git a/config_server/v1/service/Dockerfile b/config_server/v1/service/Dockerfile
new file mode 100644
index 0000000000..b75ef08846
--- /dev/null
+++ b/config_server/v1/service/Dockerfile
@@ -0,0 +1,39 @@
+# Copyright 2023 iLogtail Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FROM sls-opensource-registry.cn-shanghai.cr.aliyuncs.com/ilogtail-community-edition/ilogtail-build-linux:2.0.3 as build
+
+USER root
+WORKDIR /src
+COPY . .
+RUN go env -w GOPROXY="https://goproxy.cn,direct" && \
+    go build -o ConfigServer
+
+FROM centos:centos7.9.2009
+MAINTAINER TomYu yyuuttaaoo@gmail.com
+
+ENV container docker
+
+RUN curl -L -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
+
+RUN yum update -y && yum upgrade -y && yum -y clean all && rm -fr /var/cache && rm -rf /core.*
+
+WORKDIR /config_server
+COPY --from=build /src/ConfigServer /config_server/ConfigServer
+COPY --from=build /src/setting/setting.json /config_server/setting/setting.json
+RUN chmod 755 /config_server/ConfigServer && \
+    sed -i 's/127\.0\.0\.1/0\.0\.0\.0/' setting/setting.json
+ENV GIN_MODE=release
+
+CMD ["./ConfigServer"]
diff --git a/config_server/v1/service/common/data_type.go b/config_server/v1/service/common/data_type.go
new file mode 100644
index 0000000000..214e4a9c07
--- /dev/null
+++ b/config_server/v1/service/common/data_type.go
@@ -0,0 +1,23 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package common
+
+const (
+	TypeAgentAttributes string = "AGENT_ATTRIBUTES"
+	TypeAgent           string = "AGENT"
+	TypeConfigDetail    string = "CONFIG_DETAIL"
+	TypeAgentGROUP      string = "AGENTGROUP"
+	TypeCommand         string = "COMMAND"
+)
diff --git a/config_server/v1/service/common/http_response.go b/config_server/v1/service/common/http_response.go
new file mode 100644
index 0000000000..3b1b597afd
--- /dev/null
+++ b/config_server/v1/service/common/http_response.go
@@ -0,0 +1,35 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package common
+
+type httpStatus struct {
+	Status int
+	Code   string
+}
+
+var (
+	Accept                 = httpStatus{200, "Accept"}
+	BadRequest             = httpStatus{400, "BadRequest"}
+	ConfigAlreadyExist     = httpStatus{400, "ConfigAlreadyExist"}
+	ConfigNotExist         = httpStatus{404, "ConfigNotExist"}
+	InternalServerError    = httpStatus{500, "InternalServerError"}
+	InvalidParameter       = httpStatus{400, "InvalidParameter"}
+	AgentAlreadyExist      = httpStatus{400, "AgentAlreadyExist"}
+	AgentGroupAlreadyExist = httpStatus{400, "AgentGroupAlreadyExist"}
+	AgentGroupNotExist     = httpStatus{404, "AgentGroupNotExist"}
+	AgentNotExist          = httpStatus{404, "AgentNotExist"}
+	RequestTimeout         = httpStatus{500, "RequestTimeout"}
+	ServerBusy             = httpStatus{503, "ServerBusy"}
+)
diff --git a/config_server/v1/service/common/json_file.go b/config_server/v1/service/common/json_file.go
new file mode 100644
index 0000000000..38bd87e136
--- /dev/null
+++ b/config_server/v1/service/common/json_file.go
@@ -0,0 +1,64 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package common
+
+import (
+	"encoding/json"
+	"log"
+	"os"
+	"path/filepath"
+)
+
+func ReadJSON(path string, ptr interface{}) error {
+	file, openErr := os.Open(filepath.Clean(path))
+	if openErr != nil {
+		return openErr
+	}
+	defer func() {
+		if closeErr := file.Close(); closeErr != nil {
+			log.Println("Error closing file: " + closeErr.Error())
+		}
+	}()
+
+	decoder := json.NewDecoder(file)
+	decoderErr := decoder.Decode(&ptr)
+	if decoderErr != nil {
+		return decoderErr
+	}
+	return nil
+}
+
+func WriteJSON(path string, data interface{}) error {
+	dataString, marshalErr := json.Marshal(data)
+	if marshalErr != nil {
+		return marshalErr
+	}
+
+	file, openErr := os.OpenFile(filepath.Clean(path), os.O_RDWR|os.O_TRUNC, os.ModeAppend)
+	if openErr != nil {
+		return openErr
+	}
+
+	_, writeErr := file.WriteString(string(dataString))
+	if writeErr != nil {
+		return writeErr
+	}
+	defer func() {
+		if closeErr := file.Close(); closeErr != nil {
+			log.Println("Error closing file: " + closeErr.Error())
+		}
+	}()
+	return nil
+}
diff --git a/config_server/v1/service/common/queue.go b/config_server/v1/service/common/queue.go
new file mode 100644
index 0000000000..93cd1a9b02
--- /dev/null
+++ b/config_server/v1/service/common/queue.go
@@ -0,0 +1,84 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use q file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package common
+
+type (
+	Queue struct {
+		top    *node
+		rear   *node
+		length int
+	}
+
+	node struct {
+		pre   *node
+		next  *node
+		value interface{}
+	}
+)
+
+// Create a new queue
+func NewQueue() *Queue {
+	return &Queue{nil, nil, 0}
+}
+
+func (q *Queue) Len() int {
+	return q.length
+}
+
+func (q *Queue) Empty() bool {
+	return q.length == 0
+}
+
+func (q *Queue) Front() interface{} {
+	if q.top == nil {
+		return nil
+	}
+	return q.top.value
+}
+
+func (q *Queue) Push(v interface{}) {
+	n := &node{nil, nil, v}
+	if q.length == 0 {
+		q.top = n
+		q.rear = q.top
+	} else {
+		n.pre = q.rear
+		q.rear.next = n
+		q.rear = n
+	}
+	q.length++
+}
+
+func (q *Queue) Pop() interface{} {
+	if q.length == 0 {
+		return nil
+	}
+	n := q.top
+	if q.top.next == nil {
+		q.top = nil
+	} else {
+		q.top = q.top.next
+		q.top.pre.next = nil
+		q.top.pre = nil
+	}
+	q.length--
+	return n.value
+}
+
+func (q *Queue) Clear() {
+	for !q.Empty() {
+		q.Pop()
+	}
+}
diff --git a/config_server/v1/service/example/setting.json b/config_server/v1/service/example/setting.json
new file mode 100644
index 0000000000..27de7cf291
--- /dev/null
+++ b/config_server/v1/service/example/setting.json
@@ -0,0 +1,8 @@
+{
+    "ip":"127.0.0.1",
+    "store_mode": "leveldb",
+    "port": "8899",
+    "db_path": "./DB",
+    "agent_message_update_interval": 1,
+    "collection_config_sync_interval": 3
+}
\ No newline at end of file
diff --git a/config_server/v1/service/go.mod b/config_server/v1/service/go.mod
new file mode 100644
index 0000000000..001b8f5fd0
--- /dev/null
+++ b/config_server/v1/service/go.mod
@@ -0,0 +1,53 @@
+module config-server
+
+go 1.19
+
+require (
+	github.com/gin-gonic/gin v1.8.1
+	github.com/syndtr/goleveldb v1.0.0
+	google.golang.org/protobuf v1.28.0
+	gorm.io/driver/mysql v1.5.4
+	gorm.io/driver/postgres v1.5.7
+	gorm.io/driver/sqlite v1.5.5
+	gorm.io/driver/sqlserver v1.5.3
+	gorm.io/gorm v1.25.7
+)
+
+require (
+	github.com/go-sql-driver/mysql v1.7.0 // indirect
+	github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
+	github.com/golang-sql/sqlexp v0.1.0 // indirect
+	github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
+	github.com/jackc/pgpassfile v1.0.0 // indirect
+	github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
+	github.com/jackc/pgx/v5 v5.4.3 // indirect
+	github.com/jinzhu/inflection v1.0.0 // indirect
+	github.com/jinzhu/now v1.1.5 // indirect
+	github.com/jtolds/gls v4.20.0+incompatible // indirect
+	github.com/mattn/go-sqlite3 v1.14.17 // indirect
+	github.com/microsoft/go-mssqldb v1.6.0 // indirect
+	github.com/smartystreets/assertions v1.2.0 // indirect
+)
+
+require (
+	github.com/gin-contrib/sse v0.1.0 // indirect
+	github.com/go-playground/locales v0.14.0 // indirect
+	github.com/go-playground/universal-translator v0.18.0 // indirect
+	github.com/go-playground/validator/v10 v10.10.0 // indirect
+	github.com/goccy/go-json v0.9.7 // indirect
+	github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/leodido/go-urn v1.2.1 // indirect
+	github.com/mattn/go-isatty v0.0.14 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/pelletier/go-toml/v2 v2.0.1 // indirect
+	github.com/smartystreets/goconvey v1.7.2
+	github.com/ugorji/go/codec v1.2.7 // indirect
+	golang.org/x/crypto v0.14.0 // indirect
+	golang.org/x/net v0.14.0 // indirect
+	golang.org/x/sys v0.13.0 // indirect
+	golang.org/x/text v0.13.0 // indirect
+	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
+)
diff --git a/config_server/v1/service/go.sum b/config_server/v1/service/go.sum
new file mode 100644
index 0000000000..f3b80eaa71
--- /dev/null
+++ b/config_server/v1/service/go.sum
@@ -0,0 +1,252 @@
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 h1:/iHxaJhsFr0+xVFfbMr5vxz848jyiWuIEDhYq3y5odY=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.2.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
+github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0 h1:yfJe15aSwEQ6Oo6J+gdfdulPNoZ3TEhmbhLIoxZcA+U=
+github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0/go.mod h1:Q28U+75mpCaSCDowNEmhIo/rmgdkqmkmzI7N6TGR4UY=
+github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4=
+github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0/go.mod h1:cw4zVQgBby0Z5f2v0itn6se2dDP17nTjbZFXW5uPyHA=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpCKs6LGGLAhwBARt9632unrVcI6i8s/8os=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
+github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
+github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
+github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
+github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
+github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
+github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
+github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
+github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
+github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
+github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
+github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
+github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
+github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
+github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
+github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
+github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
+github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
+github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY=
+github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
+github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
+github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
+github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
+github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
+github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
+github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
+github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
+github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
+github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
+github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
+github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
+github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc=
+github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
+github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
+github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
+github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
+github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
+github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
+github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
+github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
+github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
+github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
+github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
+github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
+github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
+github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
+github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
+golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
+golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
+golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
+golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gorm.io/driver/mysql v1.5.4 h1:igQmHfKcbaTVyAIHNhhB888vvxh8EdQ2uSUT0LPcBso=
+gorm.io/driver/mysql v1.5.4/go.mod h1:9rYxJph/u9SWkWc9yY4XJ1F/+xO0S/ChOmbk3+Z5Tvs=
+gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
+gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
+gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E=
+gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE=
+gorm.io/driver/sqlserver v1.5.3 h1:rjupPS4PVw+rjJkfvr8jn2lJ8BMhT4UW5FwuJY0P3Z0=
+gorm.io/driver/sqlserver v1.5.3/go.mod h1:B+CZ0/7oFJ6tAlefsKoyxdgDCXJKSgwS2bMOQZT0I00=
+gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
+gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A=
+gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
diff --git a/config_server/v1/service/interface/agent/collection_config.go b/config_server/v1/service/interface/agent/collection_config.go
new file mode 100644
index 0000000000..1bf463baa1
--- /dev/null
+++ b/config_server/v1/service/interface/agent/collection_config.go
@@ -0,0 +1,62 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package agent
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+
+	"config-server/common"
+	"config-server/manager"
+	proto "config-server/proto"
+)
+
+func FetchPipelineConfig(c *gin.Context) {
+	req := proto.FetchPipelineConfigRequest{}
+	res := &proto.FetchPipelineConfigResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.RequestId = req.RequestId
+
+	if req.ReqConfigs == nil {
+		req.ReqConfigs = []*proto.ConfigInfo{}
+	}
+
+	c.ProtoBuf(manager.ConfigManager().FetchPipelineConfig(&req, res))
+}
+
+func FetchAgentConfig(c *gin.Context) {
+	req := proto.FetchAgentConfigRequest{}
+	res := &proto.FetchAgentConfigResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.RequestId = req.RequestId
+
+	if req.ReqConfigs == nil {
+		req.ReqConfigs = []*proto.ConfigInfo{}
+	}
+
+	c.ProtoBuf(manager.ConfigManager().FetchAgentConfig(&req, res))
+}
diff --git a/config_server/v1/service/interface/agent/status.go b/config_server/v1/service/interface/agent/status.go
new file mode 100644
index 0000000000..6a970271d8
--- /dev/null
+++ b/config_server/v1/service/interface/agent/status.go
@@ -0,0 +1,52 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package agent
+
+import (
+	"fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+
+	"config-server/common"
+	"config-server/manager"
+	proto "config-server/proto"
+)
+
+func HeartBeat(c *gin.Context) {
+	req := proto.HeartBeatRequest{}
+	res := &proto.HeartBeatResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.RequestId = req.RequestId
+
+	if req.AgentId == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "AgentID")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	_, res = manager.AgentManager().HeartBeat(&req, res)
+	if res.Code != proto.RespCode_ACCEPT {
+		c.ProtoBuf(common.BadRequest.Status, res)
+	}
+	c.ProtoBuf(manager.ConfigManager().CheckConfigUpdatesWhenHeartbeat(&req, res))
+}
diff --git a/config_server/v1/service/interface/user/agent_group.go b/config_server/v1/service/interface/user/agent_group.go
new file mode 100644
index 0000000000..3b9a4ab3e7
--- /dev/null
+++ b/config_server/v1/service/interface/user/agent_group.go
@@ -0,0 +1,229 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package user
+
+import (
+	"fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+
+	"config-server/common"
+	"config-server/manager"
+	proto "config-server/proto"
+)
+
+func CreateAgentGroup(c *gin.Context) {
+	req := proto.CreateAgentGroupRequest{}
+	res := &proto.CreateAgentGroupResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.AgentGroup.GroupName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group need parameter %s.", "GroupName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().CreateAgentGroup(&req, res))
+}
+
+func UpdateAgentGroup(c *gin.Context) {
+	req := proto.UpdateAgentGroupRequest{}
+	res := &proto.UpdateAgentGroupResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.AgentGroup.GroupName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group need parameter %s.", "groupName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().UpdateAgentGroup(&req, res))
+}
+
+func DeleteAgentGroup(c *gin.Context) {
+	req := proto.DeleteAgentGroupRequest{}
+	res := &proto.DeleteAgentGroupResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.GroupName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group need parameter %s.", "groupName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().DeleteAgentGroup(&req, res))
+}
+
+func GetAgentGroup(c *gin.Context) {
+	req := proto.GetAgentGroupRequest{}
+	res := &proto.GetAgentGroupResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.GroupName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group need parameter %s.", "groupName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().GetAgentGroup(&req, res))
+}
+
+func ListAgentGroups(c *gin.Context) {
+	req := proto.ListAgentGroupsRequest{}
+	res := &proto.ListAgentGroupsResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	c.ProtoBuf(manager.ConfigManager().ListAgentGroups(&req, res))
+}
+
+func ListAgents(c *gin.Context) {
+	req := proto.ListAgentsRequest{}
+	res := &proto.ListAgentsResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.GroupName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "groupName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().ListAgents(&req, res))
+}
+
+func GetAppliedConfigsForAgentGroup(c *gin.Context) {
+	req := proto.GetAppliedConfigsForAgentGroupRequest{}
+	res := &proto.GetAppliedConfigsForAgentGroupResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.GroupName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "GroupName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().GetAppliedConfigsForAgentGroup(&req, res))
+}
+
+func ApplyConfigToAgentGroup(c *gin.Context) {
+	req := proto.ApplyConfigToAgentGroupRequest{}
+	res := &proto.ApplyConfigToAgentGroupResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.GroupName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "groupName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	if req.ConfigName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "configName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().ApplyConfigToAgentGroup(&req, res))
+}
+
+func RemoveConfigFromAgentGroup(c *gin.Context) {
+	req := proto.RemoveConfigFromAgentGroupRequest{}
+	res := &proto.RemoveConfigFromAgentGroupResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.GroupName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "groupName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	if req.ConfigName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "configName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().RemoveConfigFromAgentGroup(&req, res))
+}
diff --git a/config_server/v1/service/interface/user/collection_config.go b/config_server/v1/service/interface/user/collection_config.go
new file mode 100644
index 0000000000..589b4ebfc8
--- /dev/null
+++ b/config_server/v1/service/interface/user/collection_config.go
@@ -0,0 +1,165 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package user
+
+import (
+	"fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/gin-gonic/gin/binding"
+
+	"config-server/common"
+	"config-server/manager"
+	proto "config-server/proto"
+)
+
+func CreateConfig(c *gin.Context) {
+	req := proto.CreateConfigRequest{}
+	res := &proto.CreateConfigResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.ConfigDetail.Name == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "ConfigName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	if req.ConfigDetail.Detail == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "Detail")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().CreateConfig(&req, res))
+}
+
+func UpdateConfig(c *gin.Context) {
+	req := proto.UpdateConfigRequest{}
+	res := &proto.UpdateConfigResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.ConfigDetail.Name == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "ConfigName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	if req.ConfigDetail.Detail == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "Detail")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().UpdateConfig(&req, res))
+}
+
+func DeleteConfig(c *gin.Context) {
+	req := proto.DeleteConfigRequest{}
+	res := &proto.DeleteConfigResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.ConfigName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "ConfigName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().DeleteConfig(&req, res))
+}
+
+func GetConfig(c *gin.Context) {
+	req := proto.GetConfigRequest{}
+	res := &proto.GetConfigResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.ConfigName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "ConfigName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().GetConfig(&req, res))
+}
+
+func ListConfigs(c *gin.Context) {
+	req := proto.ListConfigsRequest{}
+	res := &proto.ListConfigsResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	c.ProtoBuf(manager.ConfigManager().ListConfigs(&req, res))
+}
+
+func GetAppliedAgentGroups(c *gin.Context) {
+	req := proto.GetAppliedAgentGroupsRequest{}
+	res := &proto.GetAppliedAgentGroupsResponse{}
+
+	err := c.ShouldBindBodyWith(&req, binding.ProtoBuf)
+	if err != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+	res.ResponseId = req.RequestId
+
+	if req.ConfigName == "" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Need parameter %s.", "ConfigName")
+		c.ProtoBuf(common.BadRequest.Status, res)
+		return
+	}
+
+	c.ProtoBuf(manager.ConfigManager().GetAppliedAgentGroups(&req, res))
+}
diff --git a/config_server/v1/service/manager/agent/agent_manager.go b/config_server/v1/service/manager/agent/agent_manager.go
new file mode 100644
index 0000000000..594a28ff76
--- /dev/null
+++ b/config_server/v1/service/manager/agent/agent_manager.go
@@ -0,0 +1,56 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package agentmanager
+
+import (
+	"sync"
+
+	"config-server/model"
+	"config-server/setting"
+)
+
+type AgentManager struct {
+	AgentMessageList agentMessageList
+}
+
+func (a *AgentManager) Init() {
+	a.AgentMessageList.Clear()
+	go a.updateAgentMessage(setting.GetSetting().AgentUpdateInterval)
+}
+
+// batch write message from agent to databse
+
+const (
+	optHeartbeat string = "HEARTBEAT"
+)
+
+type agentMessageList struct {
+	Heartbeat map[string]*model.Agent
+	Mutex     sync.RWMutex
+}
+
+func (a *agentMessageList) Clear() {
+	a.Heartbeat = make(map[string]*model.Agent, 0)
+}
+
+func (a *agentMessageList) Push(opt string, data interface{}) {
+	a.Mutex.Lock()
+	defer a.Mutex.Unlock()
+
+	switch opt {
+	case optHeartbeat:
+		a.Heartbeat[data.(*model.Agent).AgentID] = data.(*model.Agent)
+	}
+}
diff --git a/config_server/v1/service/manager/agent/agent_operator.go b/config_server/v1/service/manager/agent/agent_operator.go
new file mode 100644
index 0000000000..27c6cf55e2
--- /dev/null
+++ b/config_server/v1/service/manager/agent/agent_operator.go
@@ -0,0 +1,75 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package agentmanager
+
+import (
+	"log"
+	"sync"
+	"time"
+
+	"config-server/common"
+	"config-server/model"
+	proto "config-server/proto"
+	"config-server/store"
+)
+
+func (a *AgentManager) HeartBeat(req *proto.HeartBeatRequest, res *proto.HeartBeatResponse) (int, *proto.HeartBeatResponse) {
+	agent := new(model.Agent)
+	agent.AgentID = req.AgentId
+	agent.AgentType = req.AgentType
+	agent.Attributes.ParseProto(req.Attributes)
+	agent.Tags = req.Tags
+	agent.RunningStatus = req.RunningStatus
+	agent.StartupTime = req.StartupTime
+	agent.Interval = req.Interval
+
+	a.AgentMessageList.Push(optHeartbeat, agent)
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Send heartbeat success"
+	return common.Accept.Status, res
+}
+
+var wg sync.WaitGroup
+
+func (a *AgentManager) updateAgentMessage(interval int) {
+	ticker := time.NewTicker(time.Duration(interval) * time.Second)
+	defer ticker.Stop()
+
+	for range ticker.C {
+		wg.Add(1)
+		go a.batchUpdateAgentMessage()
+		wg.Wait()
+	}
+}
+
+func (a *AgentManager) batchUpdateAgentMessage() {
+	s := store.GetStore()
+	b := store.CreateBacth()
+
+	a.AgentMessageList.Mutex.Lock()
+	for k, v := range a.AgentMessageList.Heartbeat {
+		b.Update(common.TypeAgent, k, v)
+	}
+	a.AgentMessageList.Heartbeat = make(map[string]*model.Agent, 0)
+	a.AgentMessageList.Mutex.Unlock()
+
+	writeBatchErr := s.WriteBatch(b)
+	if writeBatchErr != nil {
+		log.Println(writeBatchErr)
+	}
+
+	wg.Done()
+}
diff --git a/config_server/v1/service/manager/config/agent_operator.go b/config_server/v1/service/manager/config/agent_operator.go
new file mode 100644
index 0000000000..6402583a98
--- /dev/null
+++ b/config_server/v1/service/manager/config/agent_operator.go
@@ -0,0 +1,232 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package configmanager
+
+import (
+	"fmt"
+	"log"
+	"time"
+
+	"config-server/common"
+	"config-server/model"
+	proto "config-server/proto"
+	"config-server/store"
+)
+
+func (c *ConfigManager) updateConfigList(interval int) {
+	ticker := time.NewTicker(time.Duration(interval) * time.Second)
+	defer ticker.Stop()
+
+	for range ticker.C {
+		s := store.GetStore()
+		configList, getAllErr := s.GetAll(common.TypeConfigDetail)
+		if getAllErr != nil {
+			log.Println(getAllErr)
+			continue
+		} else {
+			c.ConfigListMutex.Lock()
+			c.ConfigList = make(map[string]*model.ConfigDetail, 0)
+			for _, config := range configList {
+				c.ConfigList[config.(*model.ConfigDetail).Name] = config.(*model.ConfigDetail)
+			}
+			c.ConfigListMutex.Unlock()
+		}
+	}
+}
+
+func (c *ConfigManager) CheckConfigUpdatesWhenHeartbeat(req *proto.HeartBeatRequest, res *proto.HeartBeatResponse) (int, *proto.HeartBeatResponse) {
+	pipelineConfigs := make([]*proto.ConfigCheckResult, 0)
+	agentConfigs := make([]*proto.ConfigCheckResult, 0)
+	s := store.GetStore()
+
+	// get all configs connected to agent group whose tag is same as agent's
+	SelectedConfigs := make(map[string]*model.ConfigDetail)
+	agentGroupList, getAllErr := s.GetAll(common.TypeAgentGROUP)
+	if getAllErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getAllErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	for _, agentGroup := range agentGroupList {
+		match := func() bool {
+			for _, v := range agentGroup.(*model.AgentGroup).Tags {
+				for _, tag := range req.Tags {
+					if v.Value == tag {
+						return true
+					}
+				}
+			}
+			return false
+		}()
+		if match || agentGroup.(*model.AgentGroup).Name == "default" {
+			for k := range agentGroup.(*model.AgentGroup).AppliedConfigs {
+				// Check if config k exist
+				c.ConfigListMutex.RLock()
+				config, ok := c.ConfigList[k]
+				c.ConfigListMutex.RUnlock()
+				if !ok {
+					res.Code = proto.RespCode_INVALID_PARAMETER
+					res.Message = fmt.Sprintf("Config %s doesn't exist.", k)
+					return common.ConfigNotExist.Status, res
+				}
+
+				if config.DelTag {
+					res.Code = proto.RespCode_INVALID_PARAMETER
+					res.Message = fmt.Sprintf("Config %s doesn't exist.", k)
+					return common.ConfigNotExist.Status, res
+				}
+
+				SelectedConfigs[k] = config
+			}
+		}
+	}
+
+	// deleted or modified configs, and delete same configs in SelectedConfigs
+	for _, k := range req.PipelineConfigs {
+		config, ok := SelectedConfigs[k.Name]
+		if !ok {
+			result := new(proto.ConfigCheckResult)
+			result.Type = proto.ConfigType_PIPELINE_CONFIG
+			result.Name = k.Name
+			result.OldVersion = k.Version
+			result.NewVersion = k.Version
+			result.Context = k.Context
+			result.CheckStatus = proto.CheckStatus_DELETED
+			pipelineConfigs = append(pipelineConfigs, result)
+		} else if ok {
+			if config.Version > k.Version {
+				result := new(proto.ConfigCheckResult)
+				result.Type = proto.ConfigType_PIPELINE_CONFIG
+				result.Name = config.Name
+				result.OldVersion = k.Version
+				result.NewVersion = config.Version
+				result.Context = config.Context
+				result.CheckStatus = proto.CheckStatus_MODIFIED
+				pipelineConfigs = append(pipelineConfigs, result)
+			}
+			delete(SelectedConfigs, k.Name)
+		}
+	}
+
+	for _, k := range req.AgentConfigs {
+		config, ok := SelectedConfigs[k.Name]
+		if !ok {
+			result := new(proto.ConfigCheckResult)
+			result.Type = proto.ConfigType_AGENT_CONFIG
+			result.Name = k.Name
+			result.OldVersion = k.Version
+			result.NewVersion = k.Version
+			result.Context = k.Context
+			result.CheckStatus = proto.CheckStatus_DELETED
+			agentConfigs = append(agentConfigs, result)
+		} else if ok {
+			if config.Version > k.Version {
+				result := new(proto.ConfigCheckResult)
+				result.Type = proto.ConfigType_AGENT_CONFIG
+				result.Name = config.Name
+				result.OldVersion = k.Version
+				result.NewVersion = config.Version
+				result.Context = config.Context
+				result.CheckStatus = proto.CheckStatus_MODIFIED
+				agentConfigs = append(agentConfigs, result)
+			}
+			delete(SelectedConfigs, k.Name)
+		}
+	}
+
+	// new configs
+	for _, config := range SelectedConfigs {
+		result := new(proto.ConfigCheckResult)
+		result.Type = model.ConfigType[config.Type]
+		result.Name = config.Name
+		result.OldVersion = 0
+		result.NewVersion = config.Version
+		result.Context = config.Context
+		result.CheckStatus = proto.CheckStatus_NEW
+		switch result.Type {
+		case proto.ConfigType_AGENT_CONFIG:
+			agentConfigs = append(agentConfigs, result)
+		case proto.ConfigType_PIPELINE_CONFIG:
+			pipelineConfigs = append(pipelineConfigs, result)
+		}
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message += "Get config update infos success"
+	res.AgentCheckResults = agentConfigs
+	res.PipelineCheckResults = pipelineConfigs
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) FetchAgentConfig(req *proto.FetchAgentConfigRequest, res *proto.FetchAgentConfigResponse) (int, *proto.FetchAgentConfigResponse) {
+	ans := make([]*proto.ConfigDetail, 0)
+
+	// do something about attributes
+
+	for _, configInfo := range req.ReqConfigs {
+		c.ConfigListMutex.RLock()
+		config, ok := c.ConfigList[configInfo.Name]
+		c.ConfigListMutex.RUnlock()
+		if !ok {
+			res.Code = proto.RespCode_INVALID_PARAMETER
+			res.Message += fmt.Sprintf("Config %s doesn't exist.\n", configInfo.Name)
+			continue
+		}
+
+		if config.DelTag {
+			res.Code = proto.RespCode_INVALID_PARAMETER
+			res.Message = fmt.Sprintf("Config %s doesn't exist.\n", configInfo.Name)
+			continue
+		}
+		if config.Type == configInfo.Type.String() {
+			ans = append(ans, config.ToProto())
+		}
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Get Agent Config details success"
+	res.ConfigDetails = ans
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) FetchPipelineConfig(req *proto.FetchPipelineConfigRequest, res *proto.FetchPipelineConfigResponse) (int, *proto.FetchPipelineConfigResponse) {
+	ans := make([]*proto.ConfigDetail, 0)
+
+	for _, configInfo := range req.ReqConfigs {
+		c.ConfigListMutex.RLock()
+		config, ok := c.ConfigList[configInfo.Name]
+		c.ConfigListMutex.RUnlock()
+		if !ok {
+			res.Code = proto.RespCode_INVALID_PARAMETER
+			res.Message += fmt.Sprintf("Config %s doesn't exist.\n", configInfo.Name)
+			continue
+		}
+
+		if config.DelTag {
+			res.Code = proto.RespCode_INVALID_PARAMETER
+			res.Message = fmt.Sprintf("Config %s doesn't exist.\n", configInfo.Name)
+			continue
+		}
+		if config.Type == configInfo.Type.String() {
+			ans = append(ans, config.ToProto())
+		}
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Get Agent Config details success"
+	res.ConfigDetails = ans
+	return common.Accept.Status, res
+}
diff --git a/config_server/v1/service/manager/config/config_manager.go b/config_server/v1/service/manager/config/config_manager.go
new file mode 100644
index 0000000000..045eed4fc5
--- /dev/null
+++ b/config_server/v1/service/manager/config/config_manager.go
@@ -0,0 +1,54 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package configmanager
+
+import (
+	"sync"
+
+	"config-server/common"
+	"config-server/model"
+	"config-server/setting"
+	"config-server/store"
+)
+
+type ConfigManager struct {
+	ConfigList      map[string]*model.ConfigDetail
+	ConfigListMutex *sync.RWMutex
+}
+
+func (c *ConfigManager) Init() {
+	c.ConfigList = make(map[string]*model.ConfigDetail)
+	c.ConfigListMutex = new(sync.RWMutex)
+	go c.updateConfigList(setting.GetSetting().ConfigSyncInterval)
+
+	s := store.GetStore()
+	ok, hasErr := s.Has(common.TypeAgentGROUP, "default")
+	if hasErr != nil {
+		panic(hasErr)
+	}
+	if ok {
+		return
+	}
+	agentGroup := new(model.AgentGroup)
+	agentGroup.Name = "default"
+	agentGroup.Tags = make([]model.AgentGroupTag, 0)
+	agentGroup.AppliedConfigs = map[string]int64{}
+	agentGroup.Description = "Default agent group, include all Agents."
+
+	addErr := s.Add(common.TypeAgentGROUP, agentGroup.Name, agentGroup)
+	if addErr != nil {
+		panic(addErr)
+	}
+}
diff --git a/config_server/v1/service/manager/config/user_operator.go b/config_server/v1/service/manager/config/user_operator.go
new file mode 100644
index 0000000000..326deafcca
--- /dev/null
+++ b/config_server/v1/service/manager/config/user_operator.go
@@ -0,0 +1,691 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package configmanager
+
+import (
+	"fmt"
+	"time"
+
+	"config-server/common"
+	"config-server/model"
+	proto "config-server/proto"
+	"config-server/store"
+)
+
+func (c *ConfigManager) CreateConfig(req *proto.CreateConfigRequest, res *proto.CreateConfigResponse) (int, *proto.CreateConfigResponse) {
+	s := store.GetStore()
+
+	ok, hasErr := s.Has(common.TypeConfigDetail, req.ConfigDetail.Name)
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if ok {
+		value, getErr := s.Get(common.TypeConfigDetail, req.ConfigDetail.Name)
+		if getErr != nil {
+			res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+			res.Message = getErr.Error()
+			return common.InternalServerError.Status, res
+		}
+		config := value.(*model.ConfigDetail)
+
+		if !config.DelTag { // exsit
+			res.Code = proto.RespCode_INVALID_PARAMETER
+			res.Message = fmt.Sprintf("Config %s already exists.", req.ConfigDetail.Name)
+			return common.ConfigAlreadyExist.Status, res
+		}
+		// exist but has delete tag
+		verison := config.Version
+		config.ParseProto(req.ConfigDetail)
+		config.Version = verison + 1
+		config.DelTag = false
+
+		updateErr := s.Update(common.TypeConfigDetail, config.Name, config)
+		if updateErr != nil {
+			res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+			res.Message = updateErr.Error()
+			return common.InternalServerError.Status, res
+		}
+
+		res.Code = proto.RespCode_ACCEPT
+		res.Message = "Add config success"
+		return common.Accept.Status, res
+	}
+	// doesn't exist
+	config := new(model.ConfigDetail)
+	config.ParseProto(req.ConfigDetail)
+	config.Version = 0
+	config.DelTag = false
+
+	addErr := s.Add(common.TypeConfigDetail, config.Name, config)
+	if addErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = addErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Add config success"
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) UpdateConfig(req *proto.UpdateConfigRequest, res *proto.UpdateConfigResponse) (int, *proto.UpdateConfigResponse) {
+	s := store.GetStore()
+	ok, hasErr := s.Has(common.TypeConfigDetail, req.ConfigDetail.Name)
+
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigDetail.Name)
+		return common.ConfigNotExist.Status, res
+	}
+
+	value, getErr := s.Get(common.TypeConfigDetail, req.ConfigDetail.Name)
+	if getErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	config := value.(*model.ConfigDetail)
+
+	if config.DelTag {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigDetail.Name)
+		return common.ConfigNotExist.Status, res
+	}
+	version := config.Version
+	config.ParseProto(req.ConfigDetail)
+	config.Version = version + 1
+
+	updateErr := s.Update(common.TypeConfigDetail, config.Name, config)
+	if updateErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = updateErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Update config success"
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) DeleteConfig(req *proto.DeleteConfigRequest, res *proto.DeleteConfigResponse) (int, *proto.DeleteConfigResponse) {
+	s := store.GetStore()
+	ok, hasErr := s.Has(common.TypeConfigDetail, req.ConfigName)
+
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
+		return common.ConfigNotExist.Status, res
+	}
+	value, getErr := s.Get(common.TypeConfigDetail, req.ConfigName)
+	if getErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	config := value.(*model.ConfigDetail)
+
+	if config.DelTag {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
+		return common.ConfigNotExist.Status, res
+	}
+	// Check if this config bind with agent groups
+	checkReq := proto.GetAppliedAgentGroupsRequest{}
+	checkRes := &proto.GetAppliedAgentGroupsResponse{}
+	checkReq.ConfigName = req.ConfigName
+	status, checkRes := c.GetAppliedAgentGroups(&checkReq, checkRes)
+	if status != 200 {
+		res.Code = checkRes.Code
+		res.Message = checkRes.Message
+		return status, res
+	}
+	if len(checkRes.AgentGroupNames) > 0 {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = fmt.Sprintf("Config %s was applied to some agent groups, cannot be deleted.", req.ConfigName)
+		return common.InternalServerError.Status, res
+	}
+
+	config.DelTag = true
+	config.Version++
+
+	updateErr := s.Update(common.TypeConfigDetail, req.ConfigName, config)
+	if updateErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = updateErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Delete config success"
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) GetConfig(req *proto.GetConfigRequest, res *proto.GetConfigResponse) (int, *proto.GetConfigResponse) {
+	s := store.GetStore()
+	ok, hasErr := s.Has(common.TypeConfigDetail, req.ConfigName)
+
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
+		return common.ConfigNotExist.Status, res
+	}
+	value, getErr := s.Get(common.TypeConfigDetail, req.ConfigName)
+	if getErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	config := value.(*model.ConfigDetail)
+
+	if config.DelTag {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
+		return common.ConfigNotExist.Status, res
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Get config success"
+	res.ConfigDetail = config.ToProto()
+	return common.Accept.Status, res
+
+}
+
+func (c *ConfigManager) ListConfigs(req *proto.ListConfigsRequest, res *proto.ListConfigsResponse) (int, *proto.ListConfigsResponse) {
+	s := store.GetStore()
+	configs, getAllErr := s.GetAll(common.TypeConfigDetail)
+
+	if getAllErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getAllErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	ans := make([]model.ConfigDetail, 0)
+	for _, value := range configs {
+		config := value.(*model.ConfigDetail)
+		if !config.DelTag {
+			ans = append(ans, *config)
+		}
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Get config list success"
+	res.ConfigDetails = make([]*proto.ConfigDetail, 0)
+	for _, v := range ans {
+		res.ConfigDetails = append(res.ConfigDetails, v.ToProto())
+	}
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) GetAppliedAgentGroups(req *proto.GetAppliedAgentGroupsRequest, res *proto.GetAppliedAgentGroupsResponse) (int, *proto.GetAppliedAgentGroupsResponse) {
+	ans := make([]string, 0)
+	s := store.GetStore()
+
+	// Check config exist
+	ok, hasErr := s.Has(common.TypeConfigDetail, req.ConfigName)
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
+		return common.ConfigNotExist.Status, res
+	}
+	value, getErr := s.Get(common.TypeConfigDetail, req.ConfigName)
+	if getErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	config := value.(*model.ConfigDetail)
+
+	if config.DelTag {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
+		return common.ConfigNotExist.Status, res
+	}
+
+	// Get agent group names
+	agentGroupList, getAllErr := s.GetAll(common.TypeAgentGROUP)
+	if getAllErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getAllErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	for _, g := range agentGroupList {
+		if _, ok := g.(*model.AgentGroup).AppliedConfigs[req.ConfigName]; ok {
+			ans = append(ans, g.(*model.AgentGroup).Name)
+		}
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Get group list success"
+	res.AgentGroupNames = ans
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) CreateAgentGroup(req *proto.CreateAgentGroupRequest, res *proto.CreateAgentGroupResponse) (int, *proto.CreateAgentGroupResponse) {
+	s := store.GetStore()
+	ok, hasErr := s.Has(common.TypeAgentGROUP, req.AgentGroup.GroupName)
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group %s already exists.", req.AgentGroup.GroupName)
+		return common.AgentGroupAlreadyExist.Status, res
+	}
+	agentGroup := new(model.AgentGroup)
+	agentGroup.ParseProto(req.AgentGroup)
+	agentGroup.AppliedConfigs = make(map[string]int64, 0)
+
+	addErr := s.Add(common.TypeAgentGROUP, agentGroup.Name, agentGroup)
+	if addErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = addErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Add agent group success"
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) UpdateAgentGroup(req *proto.UpdateAgentGroupRequest, res *proto.UpdateAgentGroupResponse) (int, *proto.UpdateAgentGroupResponse) {
+	s := store.GetStore()
+	ok, hasErr := s.Has(common.TypeAgentGROUP, req.AgentGroup.GroupName)
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.AgentGroup.GroupName)
+		return common.AgentGroupNotExist.Status, res
+	}
+	value, getErr := s.Get(common.TypeAgentGROUP, req.AgentGroup.GroupName)
+	if getErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	agentGroup := value.(*model.AgentGroup)
+
+	agentGroup.ParseProto(req.AgentGroup)
+
+	updateErr := s.Update(common.TypeAgentGROUP, req.AgentGroup.GroupName, agentGroup)
+	if updateErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = updateErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Update agent group success"
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) DeleteAgentGroup(req *proto.DeleteAgentGroupRequest, res *proto.DeleteAgentGroupResponse) (int, *proto.DeleteAgentGroupResponse) {
+	s := store.GetStore()
+
+	if req.GroupName == "default" {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = "Cannot delete agent group 'default'"
+		return common.BadRequest.Status, res
+	}
+
+	ok, hasErr := s.Has(common.TypeAgentGROUP, req.GroupName)
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.GroupName)
+		return common.AgentGroupNotExist.Status, res
+	}
+	// Check if this config bind with agent groups
+	checkReq := proto.GetAppliedConfigsForAgentGroupRequest{}
+	checkRes := &proto.GetAppliedConfigsForAgentGroupResponse{}
+	checkReq.GroupName = req.GroupName
+	status, checkRes := c.GetAppliedConfigsForAgentGroup(&checkReq, checkRes)
+	if status != 200 {
+		res.Code = checkRes.Code
+		res.Message = checkRes.Message
+		return status, res
+	}
+	if len(checkRes.ConfigNames) > 0 {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = fmt.Sprintf("Agent group %s was applied to some configs, cannot be deleted.", req.GroupName)
+		return common.InternalServerError.Status, res
+	}
+
+	deleteErr := s.Delete(common.TypeAgentGROUP, req.GroupName)
+	if deleteErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = deleteErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Delete agent group success"
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) GetAgentGroup(req *proto.GetAgentGroupRequest, res *proto.GetAgentGroupResponse) (int, *proto.GetAgentGroupResponse) {
+	s := store.GetStore()
+	ok, hasErr := s.Has(common.TypeAgentGROUP, req.GroupName)
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.GroupName)
+		return common.AgentGroupNotExist.Status, res
+	}
+	agentGroup, getErr := s.Get(common.TypeAgentGROUP, req.GroupName)
+	if getErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Get agent group success"
+	res.AgentGroup = agentGroup.(*model.AgentGroup).ToProto()
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) ListAgentGroups(req *proto.ListAgentGroupsRequest, res *proto.ListAgentGroupsResponse) (int, *proto.ListAgentGroupsResponse) {
+	s := store.GetStore()
+	agentGroupList, getAllErr := s.GetAll(common.TypeAgentGROUP)
+	if getAllErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		return common.InternalServerError.Status, res
+	}
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Get agent group list success"
+	res.AgentGroups = []*proto.AgentGroup{}
+	for _, v := range agentGroupList {
+		res.AgentGroups = append(res.AgentGroups, v.(*model.AgentGroup).ToProto())
+	}
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) ListAgents(req *proto.ListAgentsRequest, res *proto.ListAgentsResponse) (int, *proto.ListAgentsResponse) {
+	ans := make([]*proto.Agent, 0)
+	s := store.GetStore()
+
+	var agentGroup *model.AgentGroup
+
+	// get agent group
+	ok, hasErr := s.Has(common.TypeAgentGROUP, req.GroupName)
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.GroupName)
+		return common.AgentGroupNotExist.Status, res
+	}
+	value, getErr := s.Get(common.TypeAgentGROUP, req.GroupName)
+	if getErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	agentGroup = value.(*model.AgentGroup)
+
+	agentList, getAllErr := s.GetAll(common.TypeAgent)
+	if getAllErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getAllErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	for _, v := range agentList {
+		agent := v.(*model.Agent)
+		match := func() bool {
+			for _, v := range agentGroup.Tags {
+				for _, tag := range agent.Tags {
+					if v.Value == tag {
+						return true
+					}
+				}
+			}
+			return false
+		}()
+		if match || agentGroup.Name == "default" {
+			ans = append(ans, agent.ToProto())
+		}
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Get agent list success"
+	res.Agents = ans
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) GetAppliedConfigsForAgentGroup(req *proto.GetAppliedConfigsForAgentGroupRequest, res *proto.GetAppliedConfigsForAgentGroupResponse) (int, *proto.GetAppliedConfigsForAgentGroupResponse) {
+	ans := make([]string, 0)
+	s := store.GetStore()
+	var agentGroup *model.AgentGroup
+
+	// Get agent group
+	ok, hasErr := s.Has(common.TypeAgentGROUP, req.GroupName)
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.GroupName)
+		return common.AgentGroupNotExist.Status, res
+	}
+	value, getErr := s.Get(common.TypeAgentGROUP, req.GroupName)
+	if getErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	agentGroup = value.(*model.AgentGroup)
+
+	for k := range agentGroup.AppliedConfigs {
+		ans = append(ans, k)
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Get agent group's applied configs success"
+	res.ConfigNames = ans
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) ApplyConfigToAgentGroup(req *proto.ApplyConfigToAgentGroupRequest, res *proto.ApplyConfigToAgentGroupResponse) (int, *proto.ApplyConfigToAgentGroupResponse) {
+	s := store.GetStore()
+	var agentGroup *model.AgentGroup
+	var config *model.ConfigDetail
+
+	// Get agent group
+	ok, hasErr := s.Has(common.TypeAgentGROUP, req.GroupName)
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.GroupName)
+		return common.AgentGroupNotExist.Status, res
+	}
+	value, getErr := s.Get(common.TypeAgentGROUP, req.GroupName)
+	if getErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	agentGroup = value.(*model.AgentGroup)
+
+	// Get config
+	ok, hasErr = s.Has(common.TypeConfigDetail, req.ConfigName)
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
+		return common.ConfigNotExist.Status, res
+	}
+	value, getErr = s.Get(common.TypeConfigDetail, req.ConfigName)
+	if getErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	config = value.(*model.ConfigDetail)
+
+	if config.DelTag {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
+		return common.ConfigNotExist.Status, res
+	}
+
+	// Check if agent group already has config
+	if agentGroup.AppliedConfigs == nil {
+		agentGroup.AppliedConfigs = make(map[string]int64)
+	}
+	if _, ok := agentGroup.AppliedConfigs[config.Name]; ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group %s already has config %s.", req.GroupName, req.ConfigName)
+		return common.ConfigAlreadyExist.Status, res
+	}
+	agentGroup.AppliedConfigs[config.Name] = time.Now().Unix()
+
+	updateErr := store.GetStore().Update(common.TypeAgentGROUP, req.GroupName, agentGroup)
+	if updateErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = updateErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Add config to agent group success"
+	return common.Accept.Status, res
+}
+
+func (c *ConfigManager) RemoveConfigFromAgentGroup(req *proto.RemoveConfigFromAgentGroupRequest, res *proto.RemoveConfigFromAgentGroupResponse) (int, *proto.RemoveConfigFromAgentGroupResponse) {
+	s := store.GetStore()
+	var agentGroup *model.AgentGroup
+	var config *model.ConfigDetail
+
+	// Get agent group
+	ok, hasErr := s.Has(common.TypeAgentGROUP, req.GroupName)
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group %s doesn't exist.", req.GroupName)
+		return common.AgentGroupNotExist.Status, res
+	}
+	value, getErr := s.Get(common.TypeAgentGROUP, req.GroupName)
+	if getErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	agentGroup = value.(*model.AgentGroup)
+
+	// Get config
+	ok, hasErr = s.Has(common.TypeConfigDetail, req.ConfigName)
+	if hasErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = hasErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	if !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
+		return common.ConfigNotExist.Status, res
+	}
+	value, getErr = s.Get(common.TypeConfigDetail, req.ConfigName)
+	if getErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = getErr.Error()
+		return common.InternalServerError.Status, res
+	}
+	config = value.(*model.ConfigDetail)
+
+	if config.DelTag {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Config %s doesn't exist.", req.ConfigName)
+		return common.ConfigNotExist.Status, res
+	}
+
+	if agentGroup.AppliedConfigs == nil {
+		agentGroup.AppliedConfigs = make(map[string]int64)
+	}
+	if _, ok := agentGroup.AppliedConfigs[config.Name]; !ok {
+		res.Code = proto.RespCode_INVALID_PARAMETER
+		res.Message = fmt.Sprintf("Agent group %s doesn't have config %s.", req.GroupName, req.ConfigName)
+		return common.ConfigNotExist.Status, res
+	}
+	delete(agentGroup.AppliedConfigs, config.Name)
+
+	updateErr := store.GetStore().Update(common.TypeAgentGROUP, req.GroupName, agentGroup)
+	if updateErr != nil {
+		res.Code = proto.RespCode_INTERNAL_SERVER_ERROR
+		res.Message = updateErr.Error()
+		return common.InternalServerError.Status, res
+	}
+
+	res.Code = proto.RespCode_ACCEPT
+	res.Message = "Remove config from agent group success"
+	return common.Accept.Status, res
+}
diff --git a/config_server/v1/service/manager/manager.go b/config_server/v1/service/manager/manager.go
new file mode 100644
index 0000000000..7af038594d
--- /dev/null
+++ b/config_server/v1/service/manager/manager.go
@@ -0,0 +1,39 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package manager
+
+import (
+	agentManager "config-server/manager/agent"
+	configManager "config-server/manager/config"
+)
+
+var myAgentManager *agentManager.AgentManager
+var myConfigManager *configManager.ConfigManager
+
+func AgentManager() *agentManager.AgentManager {
+	return myAgentManager
+}
+
+func ConfigManager() *configManager.ConfigManager {
+	return myConfigManager
+}
+
+func init() {
+	myAgentManager = new(agentManager.AgentManager)
+	myAgentManager.Init()
+
+	myConfigManager = new(configManager.ConfigManager)
+	myConfigManager.Init()
+}
diff --git a/config_server/v1/service/model/agent.go b/config_server/v1/service/model/agent.go
new file mode 100644
index 0000000000..94fda23059
--- /dev/null
+++ b/config_server/v1/service/model/agent.go
@@ -0,0 +1,140 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"config-server/common"
+	proto "config-server/proto"
+	"database/sql/driver"
+	"encoding/json"
+	"fmt"
+
+	"gorm.io/gorm"
+)
+
+type AgentAttributes struct {
+	Version  string            `json:"Version"`
+	Category string            `json:"Category"`
+	IP       string            `json:"IP"`
+	Hostname string            `json:"Hostname"`
+	Region   string            `json:"Region"`
+	Zone     string            `json:"Zone"`
+	Extras   map[string]string `json:"Extras"`
+}
+
+func (a *AgentAttributes) Scan(value interface{}) error {
+	if value == nil {
+		return nil
+	}
+
+	b, ok := value.([]byte)
+	if !ok {
+		return fmt.Errorf("value is not []byte, value: %v", value)
+	}
+
+	return json.Unmarshal(b, a)
+}
+
+func (a AgentAttributes) Value() (driver.Value, error) {
+	v, err := json.Marshal(a)
+	if err != nil {
+		return nil, err
+	}
+	return v, nil
+}
+
+func (a *AgentAttributes) ToProto() *proto.AgentAttributes {
+	pa := new(proto.AgentAttributes)
+	pa.Version = a.Version
+	pa.Category = a.Category
+	pa.Ip = a.IP
+	pa.Hostname = a.Hostname
+	pa.Region = a.Region
+	pa.Zone = a.Zone
+	pa.Extras = a.Extras
+	return pa
+}
+
+func (a *AgentAttributes) ParseProto(pa *proto.AgentAttributes) {
+	a.Version = pa.Version
+	a.Category = pa.Category
+	a.IP = pa.Ip
+	a.Hostname = pa.Hostname
+	a.Region = pa.Region
+	a.Zone = pa.Zone
+	a.Extras = pa.Extras
+}
+
+type Agent struct {
+	AgentID        string          `json:"AgentID" gorm:"primaryKey;column:agent_id"`
+	AgentType      string          `json:"AgentType"`
+	Attributes     AgentAttributes `json:"Attributes"`
+	Tags           []string        `json:"Tags" gorm:"-"`
+	SerializedTags string          `json:"-" gorm:"column:tags;type:json"`
+	RunningStatus  string          `json:"RunningStatus"`
+	StartupTime    int64           `json:"StartupTime"`
+	Interval       int32           `json:"Interval"`
+}
+
+func (Agent) TableName() string {
+	return common.TypeAgent
+}
+
+func (a *Agent) AfterFind(tx *gorm.DB) (err error) {
+	if a.SerializedTags == "" {
+		return nil
+	}
+	err = json.Unmarshal([]byte(a.SerializedTags), &a.Tags)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (a *Agent) BeforeSave(tx *gorm.DB) (err error) {
+	if a.Tags == nil {
+		return nil
+	}
+	data, err := json.Marshal(a.Tags)
+	if err != nil {
+		return err
+	}
+	tx.Statement.SetColumn("tags", string(data))
+
+	return nil
+}
+
+func (a *Agent) ToProto() *proto.Agent {
+	pa := new(proto.Agent)
+	pa.AgentId = a.AgentID
+	pa.AgentType = a.AgentType
+	pa.Attributes = a.Attributes.ToProto()
+	pa.Tags = a.Tags
+	pa.RunningStatus = a.RunningStatus
+	pa.StartupTime = a.StartupTime
+	pa.Interval = a.Interval
+	return pa
+}
+
+func (a *Agent) ParseProto(pa *proto.Agent) {
+	a.AgentID = pa.AgentId
+	a.AgentType = pa.AgentType
+	a.Attributes.ParseProto(pa.Attributes)
+	a.Tags = pa.Tags
+	a.RunningStatus = pa.RunningStatus
+	a.StartupTime = pa.StartupTime
+	a.Interval = pa.Interval
+}
diff --git a/config_server/v1/service/model/agent_group.go b/config_server/v1/service/model/agent_group.go
new file mode 100644
index 0000000000..f16e996ccb
--- /dev/null
+++ b/config_server/v1/service/model/agent_group.go
@@ -0,0 +1,101 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"config-server/common"
+	proto "config-server/proto"
+	"encoding/json"
+
+	"gorm.io/gorm"
+)
+
+type AgentGroupTag struct {
+	Name  string `json:"Name"`
+	Value string `json:"Value"`
+}
+
+type AgentGroup struct {
+	Name                     string           `json:"Name" gorm:"primaryKey"`
+	Description              string           `json:"Description"`
+	Tags                     []AgentGroupTag  `json:"Tags" gorm:"-"`
+	SerializedTags           string           `json:"-" gorm:"column:tags;type:json"`
+	AppliedConfigs           map[string]int64 `json:"AppliedConfigs" gorm:"-"`
+	SerializedAppliedConfigs string           `json:"-" gorm:"column:applied_configs;type:json"`
+}
+
+func (AgentGroup) TableName() string {
+	return common.TypeAgentGROUP
+}
+
+func (a *AgentGroup) AfterFind(tx *gorm.DB) (err error) {
+	if a.SerializedTags != "" {
+		err = json.Unmarshal([]byte(a.SerializedTags), &a.Tags)
+		if err != nil {
+			return err
+		}
+	}
+	if a.SerializedAppliedConfigs != "" {
+		err = json.Unmarshal([]byte(a.SerializedAppliedConfigs), &a.AppliedConfigs)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (a *AgentGroup) BeforeSave(tx *gorm.DB) (err error) {
+	if a.Tags != nil {
+		data, err := json.Marshal(a.Tags)
+		if err != nil {
+			return err
+		}
+		tx.Statement.SetColumn("tags", string(data))
+	}
+	if a.AppliedConfigs != nil {
+		data, err := json.Marshal(a.AppliedConfigs)
+		if err != nil {
+			return err
+		}
+		tx.Statement.SetColumn("applied_configs", string(data))
+	}
+	return nil
+}
+
+func (a *AgentGroup) ToProto() *proto.AgentGroup {
+	pa := new(proto.AgentGroup)
+	pa.GroupName = a.Name
+	pa.Description = a.Description
+	pa.Tags = make([]*proto.AgentGroupTag, 0)
+	for _, v := range a.Tags {
+		tag := new(proto.AgentGroupTag)
+		tag.Name = v.Name
+		tag.Value = v.Value
+		pa.Tags = append(pa.Tags, tag)
+	}
+	return pa
+}
+
+func (a *AgentGroup) ParseProto(pa *proto.AgentGroup) {
+	a.Name = pa.GroupName
+	a.Description = pa.Description
+	a.Tags = make([]AgentGroupTag, 0)
+	for _, v := range pa.Tags {
+		tag := new(AgentGroupTag)
+		tag.Name = v.Name
+		tag.Value = v.Value
+		a.Tags = append(a.Tags, *tag)
+	}
+}
diff --git a/config_server/v1/service/model/collection_config.go b/config_server/v1/service/model/collection_config.go
new file mode 100644
index 0000000000..9b776d2dc2
--- /dev/null
+++ b/config_server/v1/service/model/collection_config.go
@@ -0,0 +1,79 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"config-server/common"
+	proto "config-server/proto"
+)
+
+var ConfigType = map[string]proto.ConfigType{
+	"PIPELINE_CONFIG": proto.ConfigType_PIPELINE_CONFIG,
+	"AGENT_CONFIG":    proto.ConfigType_AGENT_CONFIG,
+}
+
+type ConfigDetail struct {
+	Type    string `json:"Type"`
+	Name    string `json:"Name" gorm:"primaryKey"`
+	Version int64  `json:"Version"`
+	Context string `json:"Context"`
+	Detail  string `json:"Detail"`
+	DelTag  bool   `json:"DelTag"`
+}
+
+func (ConfigDetail) TableName() string {
+	return common.TypeConfigDetail
+}
+
+func (c *ConfigDetail) ToProto() *proto.ConfigDetail {
+	pc := new(proto.ConfigDetail)
+	pc.Type = ConfigType[c.Type]
+	pc.Name = c.Name
+	pc.Version = c.Version
+	pc.Context = c.Context
+	pc.Detail = c.Detail
+	return pc
+}
+
+func (c *ConfigDetail) ParseProto(pc *proto.ConfigDetail) {
+	c.Type = pc.Type.String()
+	c.Name = pc.Name
+	c.Version = pc.Version
+	c.Context = pc.Context
+	c.Detail = pc.Detail
+}
+
+type Command struct {
+	Type string            `json:"Type"`
+	Name string            `json:"Name"`
+	ID   string            `json:"ID"`
+	Args map[string]string `json:"Args"`
+}
+
+func (c *Command) ToProto() *proto.Command {
+	pc := new(proto.Command)
+	pc.Type = c.Type
+	pc.Name = c.Name
+	pc.Id = c.ID
+	pc.Args = c.Args
+	return pc
+}
+
+func (c *Command) ParseProto(pc *proto.Command) {
+	c.Type = pc.Type
+	c.Name = pc.Name
+	c.ID = pc.Id
+	c.Args = pc.Args
+}
diff --git a/config_server/v1/service/model/model_type.go b/config_server/v1/service/model/model_type.go
new file mode 100644
index 0000000000..9e0b8625ea
--- /dev/null
+++ b/config_server/v1/service/model/model_type.go
@@ -0,0 +1,36 @@
+// Copyright 2024 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"config-server/common"
+	"reflect"
+)
+
+var Models = map[string]interface{}{
+	common.TypeAgentAttributes: &AgentAttributes{},
+	common.TypeAgent:           &Agent{},
+	common.TypeConfigDetail:    &ConfigDetail{},
+	common.TypeAgentGROUP:      &AgentGroup{},
+	common.TypeCommand:         &Command{},
+}
+
+var ModelTypes = map[string]reflect.Type{
+	common.TypeAgentAttributes: reflect.TypeOf(([]*AgentAttributes)(nil)),
+	common.TypeAgent:           reflect.TypeOf(([]*Agent)(nil)),
+	common.TypeConfigDetail:    reflect.TypeOf(([]*ConfigDetail)(nil)),
+	common.TypeAgentGROUP:      reflect.TypeOf(([]*AgentGroup)(nil)),
+	common.TypeCommand:         reflect.TypeOf(([]*Command)(nil)),
+}
diff --git a/config_server/v1/service/proto/agent.pb.go b/config_server/v1/service/proto/agent.pb.go
new file mode 100644
index 0000000000..7205f9e339
--- /dev/null
+++ b/config_server/v1/service/proto/agent.pb.go
@@ -0,0 +1,1473 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.28.1
+// 	protoc        v3.6.1
+// source: agent.proto
+
+package configserver_proto
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// Define Config's type
+type ConfigType int32
+
+const (
+	ConfigType_PIPELINE_CONFIG ConfigType = 0
+	ConfigType_AGENT_CONFIG    ConfigType = 1
+)
+
+// Enum value maps for ConfigType.
+var (
+	ConfigType_name = map[int32]string{
+		0: "PIPELINE_CONFIG",
+		1: "AGENT_CONFIG",
+	}
+	ConfigType_value = map[string]int32{
+		"PIPELINE_CONFIG": 0,
+		"AGENT_CONFIG":    1,
+	}
+)
+
+func (x ConfigType) Enum() *ConfigType {
+	p := new(ConfigType)
+	*p = x
+	return p
+}
+
+func (x ConfigType) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ConfigType) Descriptor() protoreflect.EnumDescriptor {
+	return file_agent_proto_enumTypes[0].Descriptor()
+}
+
+func (ConfigType) Type() protoreflect.EnumType {
+	return &file_agent_proto_enumTypes[0]
+}
+
+func (x ConfigType) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ConfigType.Descriptor instead.
+func (ConfigType) EnumDescriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{0}
+}
+
+// Define Config's update status
+type CheckStatus int32
+
+const (
+	CheckStatus_NEW      CheckStatus = 0
+	CheckStatus_DELETED  CheckStatus = 1
+	CheckStatus_MODIFIED CheckStatus = 2
+)
+
+// Enum value maps for CheckStatus.
+var (
+	CheckStatus_name = map[int32]string{
+		0: "NEW",
+		1: "DELETED",
+		2: "MODIFIED",
+	}
+	CheckStatus_value = map[string]int32{
+		"NEW":      0,
+		"DELETED":  1,
+		"MODIFIED": 2,
+	}
+)
+
+func (x CheckStatus) Enum() *CheckStatus {
+	p := new(CheckStatus)
+	*p = x
+	return p
+}
+
+func (x CheckStatus) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (CheckStatus) Descriptor() protoreflect.EnumDescriptor {
+	return file_agent_proto_enumTypes[1].Descriptor()
+}
+
+func (CheckStatus) Type() protoreflect.EnumType {
+	return &file_agent_proto_enumTypes[1]
+}
+
+func (x CheckStatus) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use CheckStatus.Descriptor instead.
+func (CheckStatus) EnumDescriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{1}
+}
+
+// Define response code
+type RespCode int32
+
+const (
+	RespCode_ACCEPT                RespCode = 0
+	RespCode_INVALID_PARAMETER     RespCode = 1
+	RespCode_INTERNAL_SERVER_ERROR RespCode = 2
+)
+
+// Enum value maps for RespCode.
+var (
+	RespCode_name = map[int32]string{
+		0: "ACCEPT",
+		1: "INVALID_PARAMETER",
+		2: "INTERNAL_SERVER_ERROR",
+	}
+	RespCode_value = map[string]int32{
+		"ACCEPT":                0,
+		"INVALID_PARAMETER":     1,
+		"INTERNAL_SERVER_ERROR": 2,
+	}
+)
+
+func (x RespCode) Enum() *RespCode {
+	p := new(RespCode)
+	*p = x
+	return p
+}
+
+func (x RespCode) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (RespCode) Descriptor() protoreflect.EnumDescriptor {
+	return file_agent_proto_enumTypes[2].Descriptor()
+}
+
+func (RespCode) Type() protoreflect.EnumType {
+	return &file_agent_proto_enumTypes[2]
+}
+
+func (x RespCode) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use RespCode.Descriptor instead.
+func (RespCode) EnumDescriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{2}
+}
+
+// Define the Config information carried in the request
+type ConfigInfo struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Type    ConfigType `protobuf:"varint,1,opt,name=type,proto3,enum=configserver.proto.ConfigType" json:"type,omitempty"` // Required, Config's type
+	Name    string     `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`                                     // Required, Config's unique identification
+	Version int64      `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"`                              // Required, Config's version number
+	Context string     `protobuf:"bytes,4,opt,name=context,proto3" json:"context,omitempty"`                               // Config's context
+}
+
+func (x *ConfigInfo) Reset() {
+	*x = ConfigInfo{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ConfigInfo) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ConfigInfo) ProtoMessage() {}
+
+func (x *ConfigInfo) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ConfigInfo.ProtoReflect.Descriptor instead.
+func (*ConfigInfo) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *ConfigInfo) GetType() ConfigType {
+	if x != nil {
+		return x.Type
+	}
+	return ConfigType_PIPELINE_CONFIG
+}
+
+func (x *ConfigInfo) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *ConfigInfo) GetVersion() int64 {
+	if x != nil {
+		return x.Version
+	}
+	return 0
+}
+
+func (x *ConfigInfo) GetContext() string {
+	if x != nil {
+		return x.Context
+	}
+	return ""
+}
+
+// Define the result of checking the Config update status
+type ConfigCheckResult struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Type        ConfigType  `protobuf:"varint,1,opt,name=type,proto3,enum=configserver.proto.ConfigType" json:"type,omitempty"`                                   // Required, Config's type
+	Name        string      `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`                                                                       // Required, Config's unique identification
+	OldVersion  int64       `protobuf:"varint,3,opt,name=old_version,json=oldVersion,proto3" json:"old_version,omitempty"`                                        // Required, Config's current version number
+	NewVersion  int64       `protobuf:"varint,4,opt,name=new_version,json=newVersion,proto3" json:"new_version,omitempty"`                                        // Required, Config's latest version number
+	Context     string      `protobuf:"bytes,5,opt,name=context,proto3" json:"context,omitempty"`                                                                 // Config's context
+	CheckStatus CheckStatus `protobuf:"varint,6,opt,name=check_status,json=checkStatus,proto3,enum=configserver.proto.CheckStatus" json:"check_status,omitempty"` // Required, Config's update status
+}
+
+func (x *ConfigCheckResult) Reset() {
+	*x = ConfigCheckResult{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ConfigCheckResult) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ConfigCheckResult) ProtoMessage() {}
+
+func (x *ConfigCheckResult) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ConfigCheckResult.ProtoReflect.Descriptor instead.
+func (*ConfigCheckResult) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *ConfigCheckResult) GetType() ConfigType {
+	if x != nil {
+		return x.Type
+	}
+	return ConfigType_PIPELINE_CONFIG
+}
+
+func (x *ConfigCheckResult) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *ConfigCheckResult) GetOldVersion() int64 {
+	if x != nil {
+		return x.OldVersion
+	}
+	return 0
+}
+
+func (x *ConfigCheckResult) GetNewVersion() int64 {
+	if x != nil {
+		return x.NewVersion
+	}
+	return 0
+}
+
+func (x *ConfigCheckResult) GetContext() string {
+	if x != nil {
+		return x.Context
+	}
+	return ""
+}
+
+func (x *ConfigCheckResult) GetCheckStatus() CheckStatus {
+	if x != nil {
+		return x.CheckStatus
+	}
+	return CheckStatus_NEW
+}
+
+// Define Config's detail
+type ConfigDetail struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Type    ConfigType `protobuf:"varint,1,opt,name=type,proto3,enum=configserver.proto.ConfigType" json:"type,omitempty"` // Required, Config's type
+	Name    string     `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`                                     // Required, Config's unique identification
+	Version int64      `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"`                              // Required, Config's version number
+	Context string     `protobuf:"bytes,4,opt,name=context,proto3" json:"context,omitempty"`                               // Config's context
+	Detail  string     `protobuf:"bytes,5,opt,name=detail,proto3" json:"detail,omitempty"`                                 // Required, Config's detail
+}
+
+func (x *ConfigDetail) Reset() {
+	*x = ConfigDetail{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ConfigDetail) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ConfigDetail) ProtoMessage() {}
+
+func (x *ConfigDetail) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ConfigDetail.ProtoReflect.Descriptor instead.
+func (*ConfigDetail) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *ConfigDetail) GetType() ConfigType {
+	if x != nil {
+		return x.Type
+	}
+	return ConfigType_PIPELINE_CONFIG
+}
+
+func (x *ConfigDetail) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *ConfigDetail) GetVersion() int64 {
+	if x != nil {
+		return x.Version
+	}
+	return 0
+}
+
+func (x *ConfigDetail) GetContext() string {
+	if x != nil {
+		return x.Context
+	}
+	return ""
+}
+
+func (x *ConfigDetail) GetDetail() string {
+	if x != nil {
+		return x.Detail
+	}
+	return ""
+}
+
+// Define Agent's basic attributes
+type AgentAttributes struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Version  string            `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`                                                                                         // Agent's version
+	Category string            `protobuf:"bytes,2,opt,name=category,proto3" json:"category,omitempty"`                                                                                       // Agent's type(used to distinguish AGENT_CONFIG)
+	Ip       string            `protobuf:"bytes,3,opt,name=ip,proto3" json:"ip,omitempty"`                                                                                                   // Agent's ip
+	Hostname string            `protobuf:"bytes,4,opt,name=hostname,proto3" json:"hostname,omitempty"`                                                                                       // Agent's hostname
+	Region   string            `protobuf:"bytes,5,opt,name=region,proto3" json:"region,omitempty"`                                                                                           // Agent's region
+	Zone     string            `protobuf:"bytes,6,opt,name=zone,proto3" json:"zone,omitempty"`                                                                                               // Agent's zone
+	Extras   map[string]string `protobuf:"bytes,100,rep,name=extras,proto3" json:"extras,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Agent's other attributes
+}
+
+func (x *AgentAttributes) Reset() {
+	*x = AgentAttributes{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AgentAttributes) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AgentAttributes) ProtoMessage() {}
+
+func (x *AgentAttributes) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AgentAttributes.ProtoReflect.Descriptor instead.
+func (*AgentAttributes) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *AgentAttributes) GetVersion() string {
+	if x != nil {
+		return x.Version
+	}
+	return ""
+}
+
+func (x *AgentAttributes) GetCategory() string {
+	if x != nil {
+		return x.Category
+	}
+	return ""
+}
+
+func (x *AgentAttributes) GetIp() string {
+	if x != nil {
+		return x.Ip
+	}
+	return ""
+}
+
+func (x *AgentAttributes) GetHostname() string {
+	if x != nil {
+		return x.Hostname
+	}
+	return ""
+}
+
+func (x *AgentAttributes) GetRegion() string {
+	if x != nil {
+		return x.Region
+	}
+	return ""
+}
+
+func (x *AgentAttributes) GetZone() string {
+	if x != nil {
+		return x.Zone
+	}
+	return ""
+}
+
+func (x *AgentAttributes) GetExtras() map[string]string {
+	if x != nil {
+		return x.Extras
+	}
+	return nil
+}
+
+// Define command
+type Command struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Type string            `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`                                                                                         // Required, Command type
+	Name string            `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`                                                                                         // Required, Command name
+	Id   string            `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"`                                                                                             // Required, Command id
+	Args map[string]string `protobuf:"bytes,4,rep,name=args,proto3" json:"args,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Command's parameter arrays
+}
+
+func (x *Command) Reset() {
+	*x = Command{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Command) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Command) ProtoMessage() {}
+
+func (x *Command) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Command.ProtoReflect.Descriptor instead.
+func (*Command) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *Command) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+func (x *Command) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *Command) GetId() string {
+	if x != nil {
+		return x.Id
+	}
+	return ""
+}
+
+func (x *Command) GetArgs() map[string]string {
+	if x != nil {
+		return x.Args
+	}
+	return nil
+}
+
+// Agent sends requests to the ConfigServer to send heartbeats, get config updates and receive commands.
+type HeartBeatRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId       string           `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	AgentId         string           `protobuf:"bytes,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`                         // Required, Agent's unique identification
+	AgentType       string           `protobuf:"bytes,3,opt,name=agent_type,json=agentType,proto3" json:"agent_type,omitempty"`                   // Required, Agent's type(ilogtail, ..)
+	Attributes      *AgentAttributes `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"`                                  // Agent's basic attributes
+	Tags            []string         `protobuf:"bytes,5,rep,name=tags,proto3" json:"tags,omitempty"`                                              // Agent's tags
+	RunningStatus   string           `protobuf:"bytes,6,opt,name=running_status,json=runningStatus,proto3" json:"running_status,omitempty"`       // Required, Agent's running status
+	StartupTime     int64            `protobuf:"varint,7,opt,name=startup_time,json=startupTime,proto3" json:"startup_time,omitempty"`            // Required, Agent's startup time
+	Interval        int32            `protobuf:"varint,8,opt,name=interval,proto3" json:"interval,omitempty"`                                     // Agent's heartbeat interval
+	PipelineConfigs []*ConfigInfo    `protobuf:"bytes,9,rep,name=pipeline_configs,json=pipelineConfigs,proto3" json:"pipeline_configs,omitempty"` // Information about the current PIPELINE_CONFIG held by the Agent
+	AgentConfigs    []*ConfigInfo    `protobuf:"bytes,10,rep,name=agent_configs,json=agentConfigs,proto3" json:"agent_configs,omitempty"`         // Information about the current AGENT_CONFIG held by the Agent
+}
+
+func (x *HeartBeatRequest) Reset() {
+	*x = HeartBeatRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *HeartBeatRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*HeartBeatRequest) ProtoMessage() {}
+
+func (x *HeartBeatRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use HeartBeatRequest.ProtoReflect.Descriptor instead.
+func (*HeartBeatRequest) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *HeartBeatRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *HeartBeatRequest) GetAgentId() string {
+	if x != nil {
+		return x.AgentId
+	}
+	return ""
+}
+
+func (x *HeartBeatRequest) GetAgentType() string {
+	if x != nil {
+		return x.AgentType
+	}
+	return ""
+}
+
+func (x *HeartBeatRequest) GetAttributes() *AgentAttributes {
+	if x != nil {
+		return x.Attributes
+	}
+	return nil
+}
+
+func (x *HeartBeatRequest) GetTags() []string {
+	if x != nil {
+		return x.Tags
+	}
+	return nil
+}
+
+func (x *HeartBeatRequest) GetRunningStatus() string {
+	if x != nil {
+		return x.RunningStatus
+	}
+	return ""
+}
+
+func (x *HeartBeatRequest) GetStartupTime() int64 {
+	if x != nil {
+		return x.StartupTime
+	}
+	return 0
+}
+
+func (x *HeartBeatRequest) GetInterval() int32 {
+	if x != nil {
+		return x.Interval
+	}
+	return 0
+}
+
+func (x *HeartBeatRequest) GetPipelineConfigs() []*ConfigInfo {
+	if x != nil {
+		return x.PipelineConfigs
+	}
+	return nil
+}
+
+func (x *HeartBeatRequest) GetAgentConfigs() []*ConfigInfo {
+	if x != nil {
+		return x.AgentConfigs
+	}
+	return nil
+}
+
+// ConfigServer's response to Agent's heartbeats
+type HeartBeatResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId            string               `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	Code                 RespCode             `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message              string               `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	PipelineCheckResults []*ConfigCheckResult `protobuf:"bytes,4,rep,name=pipeline_check_results,json=pipelineCheckResults,proto3" json:"pipeline_check_results,omitempty"` // Agent's PIPELINE_CONFIG update status
+	AgentCheckResults    []*ConfigCheckResult `protobuf:"bytes,5,rep,name=agent_check_results,json=agentCheckResults,proto3" json:"agent_check_results,omitempty"`          // Agent's AGENT_CONFIG update status
+	CustomCommands       []*Command           `protobuf:"bytes,6,rep,name=custom_commands,json=customCommands,proto3" json:"custom_commands,omitempty"`                     // Agent received commands
+}
+
+func (x *HeartBeatResponse) Reset() {
+	*x = HeartBeatResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *HeartBeatResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*HeartBeatResponse) ProtoMessage() {}
+
+func (x *HeartBeatResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use HeartBeatResponse.ProtoReflect.Descriptor instead.
+func (*HeartBeatResponse) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *HeartBeatResponse) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *HeartBeatResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *HeartBeatResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *HeartBeatResponse) GetPipelineCheckResults() []*ConfigCheckResult {
+	if x != nil {
+		return x.PipelineCheckResults
+	}
+	return nil
+}
+
+func (x *HeartBeatResponse) GetAgentCheckResults() []*ConfigCheckResult {
+	if x != nil {
+		return x.AgentCheckResults
+	}
+	return nil
+}
+
+func (x *HeartBeatResponse) GetCustomCommands() []*Command {
+	if x != nil {
+		return x.CustomCommands
+	}
+	return nil
+}
+
+// API: /Agent/FetchPipelineConfig/
+// Agent request to ConfigServer, pulling details of the PIPELINE_CONFIG
+type FetchPipelineConfigRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId  string        `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	AgentId    string        `protobuf:"bytes,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`          // Required, Agent's unique identification
+	ReqConfigs []*ConfigInfo `protobuf:"bytes,3,rep,name=req_configs,json=reqConfigs,proto3" json:"req_configs,omitempty"` // PIPELINE_CONFIGs that Agent requires for full information
+}
+
+func (x *FetchPipelineConfigRequest) Reset() {
+	*x = FetchPipelineConfigRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FetchPipelineConfigRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FetchPipelineConfigRequest) ProtoMessage() {}
+
+func (x *FetchPipelineConfigRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FetchPipelineConfigRequest.ProtoReflect.Descriptor instead.
+func (*FetchPipelineConfigRequest) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *FetchPipelineConfigRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *FetchPipelineConfigRequest) GetAgentId() string {
+	if x != nil {
+		return x.AgentId
+	}
+	return ""
+}
+
+func (x *FetchPipelineConfigRequest) GetReqConfigs() []*ConfigInfo {
+	if x != nil {
+		return x.ReqConfigs
+	}
+	return nil
+}
+
+// ConfigServer response to Agent's request
+type FetchPipelineConfigResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId     string          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	Code          RespCode        `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message       string          `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	ConfigDetails []*ConfigDetail `protobuf:"bytes,4,rep,name=config_details,json=configDetails,proto3" json:"config_details,omitempty"` // PIPELINE_CONFIGs' detail
+}
+
+func (x *FetchPipelineConfigResponse) Reset() {
+	*x = FetchPipelineConfigResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FetchPipelineConfigResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FetchPipelineConfigResponse) ProtoMessage() {}
+
+func (x *FetchPipelineConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FetchPipelineConfigResponse.ProtoReflect.Descriptor instead.
+func (*FetchPipelineConfigResponse) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *FetchPipelineConfigResponse) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *FetchPipelineConfigResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *FetchPipelineConfigResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *FetchPipelineConfigResponse) GetConfigDetails() []*ConfigDetail {
+	if x != nil {
+		return x.ConfigDetails
+	}
+	return nil
+}
+
+// API: /Agent/FetchAgentConfig/
+// Agent request to ConfigServer, pulling details of the AGENT_CONFIG
+type FetchAgentConfigRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId  string           `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	AgentId    string           `protobuf:"bytes,2,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`          // Required, Agent's unique identification
+	Attributes *AgentAttributes `protobuf:"bytes,3,opt,name=attributes,proto3" json:"attributes,omitempty"`                   // Required, Agent's basic attributes
+	ReqConfigs []*ConfigInfo    `protobuf:"bytes,4,rep,name=req_configs,json=reqConfigs,proto3" json:"req_configs,omitempty"` // AGENT_CONFIGs that Agent requires for full information
+}
+
+func (x *FetchAgentConfigRequest) Reset() {
+	*x = FetchAgentConfigRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FetchAgentConfigRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FetchAgentConfigRequest) ProtoMessage() {}
+
+func (x *FetchAgentConfigRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FetchAgentConfigRequest.ProtoReflect.Descriptor instead.
+func (*FetchAgentConfigRequest) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *FetchAgentConfigRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *FetchAgentConfigRequest) GetAgentId() string {
+	if x != nil {
+		return x.AgentId
+	}
+	return ""
+}
+
+func (x *FetchAgentConfigRequest) GetAttributes() *AgentAttributes {
+	if x != nil {
+		return x.Attributes
+	}
+	return nil
+}
+
+func (x *FetchAgentConfigRequest) GetReqConfigs() []*ConfigInfo {
+	if x != nil {
+		return x.ReqConfigs
+	}
+	return nil
+}
+
+// ConfigServer response to Agent's request
+type FetchAgentConfigResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId     string          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	Code          RespCode        `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message       string          `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	ConfigDetails []*ConfigDetail `protobuf:"bytes,4,rep,name=config_details,json=configDetails,proto3" json:"config_details,omitempty"` // AGENT_CONFIGs' detail
+}
+
+func (x *FetchAgentConfigResponse) Reset() {
+	*x = FetchAgentConfigResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_agent_proto_msgTypes[10]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FetchAgentConfigResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FetchAgentConfigResponse) ProtoMessage() {}
+
+func (x *FetchAgentConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_agent_proto_msgTypes[10]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FetchAgentConfigResponse.ProtoReflect.Descriptor instead.
+func (*FetchAgentConfigResponse) Descriptor() ([]byte, []int) {
+	return file_agent_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *FetchAgentConfigResponse) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *FetchAgentConfigResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *FetchAgentConfigResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *FetchAgentConfigResponse) GetConfigDetails() []*ConfigDetail {
+	if x != nil {
+		return x.ConfigDetails
+	}
+	return nil
+}
+
+var File_agent_proto protoreflect.FileDescriptor
+
+var file_agent_proto_rawDesc = []byte{
+	0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x22, 0x88, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f,
+	0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e,
+	0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04,
+	0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,
+	0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
+	0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0xfb, 0x01, 0x0a,
+	0x11, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75,
+	0x6c, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
+	0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x79, 0x70, 0x65,
+	0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x6c,
+	0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
+	0x0a, 0x6f, 0x6c, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6e,
+	0x65, 0x77, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03,
+	0x52, 0x0a, 0x6e, 0x65, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63,
+	0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x42, 0x0a, 0x0c, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f,
+	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0b, 0x63,
+	0x68, 0x65, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xa2, 0x01, 0x0a, 0x0c, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x32, 0x0a, 0x04, 0x74,
+	0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12,
+	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a,
+	0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22,
+	0xa3, 0x02, 0x0a, 0x0f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
+	0x74, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a,
+	0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73,
+	0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73,
+	0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18,
+	0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a,
+	0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x7a, 0x6f, 0x6e,
+	0x65, 0x12, 0x47, 0x0a, 0x06, 0x65, 0x78, 0x74, 0x72, 0x61, 0x73, 0x18, 0x64, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72,
+	0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x73, 0x45, 0x6e, 0x74,
+	0x72, 0x79, 0x52, 0x06, 0x65, 0x78, 0x74, 0x72, 0x61, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x45, 0x78,
+	0x74, 0x72, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
+	0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
+	0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb5, 0x01, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+	0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x04, 0x61, 0x72, 0x67,
+	0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6d,
+	0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x41, 0x72, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04,
+	0x61, 0x72, 0x67, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x41, 0x72, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72,
+	0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
+	0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xba, 0x03,
+	0x0a, 0x10, 0x48, 0x65, 0x61, 0x72, 0x74, 0x42, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
+	0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a,
+	0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x61,
+	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62,
+	0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73,
+	0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04,
+	0x74, 0x61, 0x67, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x5f,
+	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x75,
+	0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73,
+	0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1a,
+	0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x49, 0x0a, 0x10, 0x70, 0x69,
+	0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x09,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72,
+	0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x43, 0x0a, 0x0d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x61, 0x67,
+	0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0xf8, 0x02, 0x0a, 0x11, 0x48,
+	0x65, 0x61, 0x72, 0x74, 0x42, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12,
+	0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64,
+	0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x5b, 0x0a, 0x16, 0x70,
+	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x72, 0x65,
+	0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75,
+	0x6c, 0x74, 0x52, 0x14, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x68, 0x65, 0x63,
+	0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x55, 0x0a, 0x13, 0x61, 0x67, 0x65, 0x6e,
+	0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18,
+	0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65,
+	0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x11, 0x61, 0x67,
+	0x65, 0x6e, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12,
+	0x44, 0x0a, 0x0f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+	0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f,
+	0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d,
+	0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x97, 0x01, 0x0a, 0x1a, 0x46, 0x65, 0x74, 0x63, 0x68, 0x50,
+	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x3f,
+	0x0a, 0x0b, 0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x03, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76,
+	0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49,
+	0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x72, 0x65, 0x71, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22,
+	0xd1, 0x01, 0x0a, 0x1b, 0x46, 0x65, 0x74, 0x63, 0x68, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
+	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x30,
+	0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65,
+	0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x47, 0x0a, 0x0e, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65,
+	0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65,
+	0x74, 0x61, 0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
+	0x69, 0x6c, 0x73, 0x22, 0xd9, 0x01, 0x0a, 0x17, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x67, 0x65,
+	0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x19,
+	0x0a, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x43, 0x0a, 0x0a, 0x61, 0x74, 0x74,
+	0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
+	0x65, 0x73, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x3f,
+	0x0a, 0x0b, 0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x04, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76,
+	0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49,
+	0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x72, 0x65, 0x71, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22,
+	0xce, 0x01, 0x0a, 0x18, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63,
+	0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52,
+	0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a,
+	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x47, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73,
+	0x2a, 0x33, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x13,
+	0x0a, 0x0f, 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49,
+	0x47, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x47, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4e,
+	0x46, 0x49, 0x47, 0x10, 0x01, 0x2a, 0x31, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x12, 0x07, 0x0a, 0x03, 0x4e, 0x45, 0x57, 0x10, 0x00, 0x12, 0x0b, 0x0a,
+	0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x4f,
+	0x44, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x48, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70,
+	0x43, 0x6f, 0x64, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, 0x00,
+	0x12, 0x15, 0x0a, 0x11, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x50, 0x41, 0x52, 0x41,
+	0x4d, 0x45, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x4e, 0x54, 0x45, 0x52,
+	0x4e, 0x41, 0x4c, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52,
+	0x10, 0x02, 0x42, 0x16, 0x5a, 0x14, 0x2e, 0x3b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65,
+	0x72, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x33,
+}
+
+var (
+	file_agent_proto_rawDescOnce sync.Once
+	file_agent_proto_rawDescData = file_agent_proto_rawDesc
+)
+
+func file_agent_proto_rawDescGZIP() []byte {
+	file_agent_proto_rawDescOnce.Do(func() {
+		file_agent_proto_rawDescData = protoimpl.X.CompressGZIP(file_agent_proto_rawDescData)
+	})
+	return file_agent_proto_rawDescData
+}
+
+var file_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
+var file_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
+var file_agent_proto_goTypes = []interface{}{
+	(ConfigType)(0),                     // 0: configserver.proto.ConfigType
+	(CheckStatus)(0),                    // 1: configserver.proto.CheckStatus
+	(RespCode)(0),                       // 2: configserver.proto.RespCode
+	(*ConfigInfo)(nil),                  // 3: configserver.proto.ConfigInfo
+	(*ConfigCheckResult)(nil),           // 4: configserver.proto.ConfigCheckResult
+	(*ConfigDetail)(nil),                // 5: configserver.proto.ConfigDetail
+	(*AgentAttributes)(nil),             // 6: configserver.proto.AgentAttributes
+	(*Command)(nil),                     // 7: configserver.proto.Command
+	(*HeartBeatRequest)(nil),            // 8: configserver.proto.HeartBeatRequest
+	(*HeartBeatResponse)(nil),           // 9: configserver.proto.HeartBeatResponse
+	(*FetchPipelineConfigRequest)(nil),  // 10: configserver.proto.FetchPipelineConfigRequest
+	(*FetchPipelineConfigResponse)(nil), // 11: configserver.proto.FetchPipelineConfigResponse
+	(*FetchAgentConfigRequest)(nil),     // 12: configserver.proto.FetchAgentConfigRequest
+	(*FetchAgentConfigResponse)(nil),    // 13: configserver.proto.FetchAgentConfigResponse
+	nil,                                 // 14: configserver.proto.AgentAttributes.ExtrasEntry
+	nil,                                 // 15: configserver.proto.Command.ArgsEntry
+}
+var file_agent_proto_depIdxs = []int32{
+	0,  // 0: configserver.proto.ConfigInfo.type:type_name -> configserver.proto.ConfigType
+	0,  // 1: configserver.proto.ConfigCheckResult.type:type_name -> configserver.proto.ConfigType
+	1,  // 2: configserver.proto.ConfigCheckResult.check_status:type_name -> configserver.proto.CheckStatus
+	0,  // 3: configserver.proto.ConfigDetail.type:type_name -> configserver.proto.ConfigType
+	14, // 4: configserver.proto.AgentAttributes.extras:type_name -> configserver.proto.AgentAttributes.ExtrasEntry
+	15, // 5: configserver.proto.Command.args:type_name -> configserver.proto.Command.ArgsEntry
+	6,  // 6: configserver.proto.HeartBeatRequest.attributes:type_name -> configserver.proto.AgentAttributes
+	3,  // 7: configserver.proto.HeartBeatRequest.pipeline_configs:type_name -> configserver.proto.ConfigInfo
+	3,  // 8: configserver.proto.HeartBeatRequest.agent_configs:type_name -> configserver.proto.ConfigInfo
+	2,  // 9: configserver.proto.HeartBeatResponse.code:type_name -> configserver.proto.RespCode
+	4,  // 10: configserver.proto.HeartBeatResponse.pipeline_check_results:type_name -> configserver.proto.ConfigCheckResult
+	4,  // 11: configserver.proto.HeartBeatResponse.agent_check_results:type_name -> configserver.proto.ConfigCheckResult
+	7,  // 12: configserver.proto.HeartBeatResponse.custom_commands:type_name -> configserver.proto.Command
+	3,  // 13: configserver.proto.FetchPipelineConfigRequest.req_configs:type_name -> configserver.proto.ConfigInfo
+	2,  // 14: configserver.proto.FetchPipelineConfigResponse.code:type_name -> configserver.proto.RespCode
+	5,  // 15: configserver.proto.FetchPipelineConfigResponse.config_details:type_name -> configserver.proto.ConfigDetail
+	6,  // 16: configserver.proto.FetchAgentConfigRequest.attributes:type_name -> configserver.proto.AgentAttributes
+	3,  // 17: configserver.proto.FetchAgentConfigRequest.req_configs:type_name -> configserver.proto.ConfigInfo
+	2,  // 18: configserver.proto.FetchAgentConfigResponse.code:type_name -> configserver.proto.RespCode
+	5,  // 19: configserver.proto.FetchAgentConfigResponse.config_details:type_name -> configserver.proto.ConfigDetail
+	20, // [20:20] is the sub-list for method output_type
+	20, // [20:20] is the sub-list for method input_type
+	20, // [20:20] is the sub-list for extension type_name
+	20, // [20:20] is the sub-list for extension extendee
+	0,  // [0:20] is the sub-list for field type_name
+}
+
+func init() { file_agent_proto_init() }
+func file_agent_proto_init() {
+	if File_agent_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_agent_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ConfigInfo); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ConfigCheckResult); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ConfigDetail); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AgentAttributes); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Command); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*HeartBeatRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*HeartBeatResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FetchPipelineConfigRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FetchPipelineConfigResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FetchAgentConfigRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_agent_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FetchAgentConfigResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_agent_proto_rawDesc,
+			NumEnums:      3,
+			NumMessages:   13,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_agent_proto_goTypes,
+		DependencyIndexes: file_agent_proto_depIdxs,
+		EnumInfos:         file_agent_proto_enumTypes,
+		MessageInfos:      file_agent_proto_msgTypes,
+	}.Build()
+	File_agent_proto = out.File
+	file_agent_proto_rawDesc = nil
+	file_agent_proto_goTypes = nil
+	file_agent_proto_depIdxs = nil
+}
diff --git a/config_server/v1/service/proto/user.pb.go b/config_server/v1/service/proto/user.pb.go
new file mode 100644
index 0000000000..46278c419b
--- /dev/null
+++ b/config_server/v1/service/proto/user.pb.go
@@ -0,0 +1,2856 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.28.1
+// 	protoc        v3.6.1
+// source: user.proto
+
+package configserver_proto
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type AgentGroupTag struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Name  string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (x *AgentGroupTag) Reset() {
+	*x = AgentGroupTag{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AgentGroupTag) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AgentGroupTag) ProtoMessage() {}
+
+func (x *AgentGroupTag) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AgentGroupTag.ProtoReflect.Descriptor instead.
+func (*AgentGroupTag) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *AgentGroupTag) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *AgentGroupTag) GetValue() string {
+	if x != nil {
+		return x.Value
+	}
+	return ""
+}
+
+type AgentGroup struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	GroupName   string           `protobuf:"bytes,1,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
+	Description string           `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
+	Tags        []*AgentGroupTag `protobuf:"bytes,3,rep,name=tags,proto3" json:"tags,omitempty"`
+}
+
+func (x *AgentGroup) Reset() {
+	*x = AgentGroup{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AgentGroup) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AgentGroup) ProtoMessage() {}
+
+func (x *AgentGroup) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AgentGroup.ProtoReflect.Descriptor instead.
+func (*AgentGroup) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *AgentGroup) GetGroupName() string {
+	if x != nil {
+		return x.GroupName
+	}
+	return ""
+}
+
+func (x *AgentGroup) GetDescription() string {
+	if x != nil {
+		return x.Description
+	}
+	return ""
+}
+
+func (x *AgentGroup) GetTags() []*AgentGroupTag {
+	if x != nil {
+		return x.Tags
+	}
+	return nil
+}
+
+type Agent struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	AgentId       string           `protobuf:"bytes,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"`                   // Required, Agent's unique identification
+	AgentType     string           `protobuf:"bytes,2,opt,name=agent_type,json=agentType,proto3" json:"agent_type,omitempty"`             // Required, Agent's type(ilogtail, ..)
+	Attributes    *AgentAttributes `protobuf:"bytes,3,opt,name=attributes,proto3" json:"attributes,omitempty"`                            // Agent's basic attributes
+	Tags          []string         `protobuf:"bytes,4,rep,name=tags,proto3" json:"tags,omitempty"`                                        // Agent's tags
+	RunningStatus string           `protobuf:"bytes,5,opt,name=running_status,json=runningStatus,proto3" json:"running_status,omitempty"` // Required, Agent's running status
+	StartupTime   int64            `protobuf:"varint,6,opt,name=startup_time,json=startupTime,proto3" json:"startup_time,omitempty"`      // Required, Agent's startup time
+	Interval      int32            `protobuf:"varint,7,opt,name=interval,proto3" json:"interval,omitempty"`                               // Agent's heartbeat interval
+}
+
+func (x *Agent) Reset() {
+	*x = Agent{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Agent) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Agent) ProtoMessage() {}
+
+func (x *Agent) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Agent.ProtoReflect.Descriptor instead.
+func (*Agent) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *Agent) GetAgentId() string {
+	if x != nil {
+		return x.AgentId
+	}
+	return ""
+}
+
+func (x *Agent) GetAgentType() string {
+	if x != nil {
+		return x.AgentType
+	}
+	return ""
+}
+
+func (x *Agent) GetAttributes() *AgentAttributes {
+	if x != nil {
+		return x.Attributes
+	}
+	return nil
+}
+
+func (x *Agent) GetTags() []string {
+	if x != nil {
+		return x.Tags
+	}
+	return nil
+}
+
+func (x *Agent) GetRunningStatus() string {
+	if x != nil {
+		return x.RunningStatus
+	}
+	return ""
+}
+
+func (x *Agent) GetStartupTime() int64 {
+	if x != nil {
+		return x.StartupTime
+	}
+	return 0
+}
+
+func (x *Agent) GetInterval() int32 {
+	if x != nil {
+		return x.Interval
+	}
+	return 0
+}
+
+type CreateAgentGroupRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId  string      `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	AgentGroup *AgentGroup `protobuf:"bytes,2,opt,name=agent_group,json=agentGroup,proto3" json:"agent_group,omitempty"`
+}
+
+func (x *CreateAgentGroupRequest) Reset() {
+	*x = CreateAgentGroupRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateAgentGroupRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateAgentGroupRequest) ProtoMessage() {}
+
+func (x *CreateAgentGroupRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateAgentGroupRequest.ProtoReflect.Descriptor instead.
+func (*CreateAgentGroupRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *CreateAgentGroupRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *CreateAgentGroupRequest) GetAgentGroup() *AgentGroup {
+	if x != nil {
+		return x.AgentGroup
+	}
+	return nil
+}
+
+type CreateAgentGroupResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *CreateAgentGroupResponse) Reset() {
+	*x = CreateAgentGroupResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateAgentGroupResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateAgentGroupResponse) ProtoMessage() {}
+
+func (x *CreateAgentGroupResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateAgentGroupResponse.ProtoReflect.Descriptor instead.
+func (*CreateAgentGroupResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *CreateAgentGroupResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *CreateAgentGroupResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *CreateAgentGroupResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+type UpdateAgentGroupRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId  string      `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	AgentGroup *AgentGroup `protobuf:"bytes,2,opt,name=agent_group,json=agentGroup,proto3" json:"agent_group,omitempty"`
+}
+
+func (x *UpdateAgentGroupRequest) Reset() {
+	*x = UpdateAgentGroupRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UpdateAgentGroupRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateAgentGroupRequest) ProtoMessage() {}
+
+func (x *UpdateAgentGroupRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateAgentGroupRequest.ProtoReflect.Descriptor instead.
+func (*UpdateAgentGroupRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *UpdateAgentGroupRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *UpdateAgentGroupRequest) GetAgentGroup() *AgentGroup {
+	if x != nil {
+		return x.AgentGroup
+	}
+	return nil
+}
+
+type UpdateAgentGroupResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *UpdateAgentGroupResponse) Reset() {
+	*x = UpdateAgentGroupResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UpdateAgentGroupResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateAgentGroupResponse) ProtoMessage() {}
+
+func (x *UpdateAgentGroupResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateAgentGroupResponse.ProtoReflect.Descriptor instead.
+func (*UpdateAgentGroupResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *UpdateAgentGroupResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *UpdateAgentGroupResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *UpdateAgentGroupResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+type DeleteAgentGroupRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
+}
+
+func (x *DeleteAgentGroupRequest) Reset() {
+	*x = DeleteAgentGroupRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DeleteAgentGroupRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteAgentGroupRequest) ProtoMessage() {}
+
+func (x *DeleteAgentGroupRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteAgentGroupRequest.ProtoReflect.Descriptor instead.
+func (*DeleteAgentGroupRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *DeleteAgentGroupRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *DeleteAgentGroupRequest) GetGroupName() string {
+	if x != nil {
+		return x.GroupName
+	}
+	return ""
+}
+
+type DeleteAgentGroupResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *DeleteAgentGroupResponse) Reset() {
+	*x = DeleteAgentGroupResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DeleteAgentGroupResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteAgentGroupResponse) ProtoMessage() {}
+
+func (x *DeleteAgentGroupResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteAgentGroupResponse.ProtoReflect.Descriptor instead.
+func (*DeleteAgentGroupResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *DeleteAgentGroupResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *DeleteAgentGroupResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *DeleteAgentGroupResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+type GetAgentGroupRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
+}
+
+func (x *GetAgentGroupRequest) Reset() {
+	*x = GetAgentGroupRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetAgentGroupRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAgentGroupRequest) ProtoMessage() {}
+
+func (x *GetAgentGroupRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAgentGroupRequest.ProtoReflect.Descriptor instead.
+func (*GetAgentGroupRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *GetAgentGroupRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *GetAgentGroupRequest) GetGroupName() string {
+	if x != nil {
+		return x.GroupName
+	}
+	return ""
+}
+
+type GetAgentGroupResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId string      `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code       RespCode    `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message    string      `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	AgentGroup *AgentGroup `protobuf:"bytes,4,opt,name=agent_group,json=agentGroup,proto3" json:"agent_group,omitempty"`
+}
+
+func (x *GetAgentGroupResponse) Reset() {
+	*x = GetAgentGroupResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[10]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetAgentGroupResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAgentGroupResponse) ProtoMessage() {}
+
+func (x *GetAgentGroupResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[10]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAgentGroupResponse.ProtoReflect.Descriptor instead.
+func (*GetAgentGroupResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *GetAgentGroupResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *GetAgentGroupResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *GetAgentGroupResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *GetAgentGroupResponse) GetAgentGroup() *AgentGroup {
+	if x != nil {
+		return x.AgentGroup
+	}
+	return nil
+}
+
+type ListAgentGroupsRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+}
+
+func (x *ListAgentGroupsRequest) Reset() {
+	*x = ListAgentGroupsRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListAgentGroupsRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListAgentGroupsRequest) ProtoMessage() {}
+
+func (x *ListAgentGroupsRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListAgentGroupsRequest.ProtoReflect.Descriptor instead.
+func (*ListAgentGroupsRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *ListAgentGroupsRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+type ListAgentGroupsResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId  string        `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code        RespCode      `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message     string        `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	AgentGroups []*AgentGroup `protobuf:"bytes,4,rep,name=agent_groups,json=agentGroups,proto3" json:"agent_groups,omitempty"`
+}
+
+func (x *ListAgentGroupsResponse) Reset() {
+	*x = ListAgentGroupsResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListAgentGroupsResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListAgentGroupsResponse) ProtoMessage() {}
+
+func (x *ListAgentGroupsResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListAgentGroupsResponse.ProtoReflect.Descriptor instead.
+func (*ListAgentGroupsResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *ListAgentGroupsResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *ListAgentGroupsResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *ListAgentGroupsResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *ListAgentGroupsResponse) GetAgentGroups() []*AgentGroup {
+	if x != nil {
+		return x.AgentGroups
+	}
+	return nil
+}
+
+type CreateConfigRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId    string        `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	ConfigDetail *ConfigDetail `protobuf:"bytes,2,opt,name=config_detail,json=configDetail,proto3" json:"config_detail,omitempty"`
+}
+
+func (x *CreateConfigRequest) Reset() {
+	*x = CreateConfigRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateConfigRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateConfigRequest) ProtoMessage() {}
+
+func (x *CreateConfigRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateConfigRequest.ProtoReflect.Descriptor instead.
+func (*CreateConfigRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *CreateConfigRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *CreateConfigRequest) GetConfigDetail() *ConfigDetail {
+	if x != nil {
+		return x.ConfigDetail
+	}
+	return nil
+}
+
+type CreateConfigResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *CreateConfigResponse) Reset() {
+	*x = CreateConfigResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[14]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateConfigResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateConfigResponse) ProtoMessage() {}
+
+func (x *CreateConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[14]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateConfigResponse.ProtoReflect.Descriptor instead.
+func (*CreateConfigResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *CreateConfigResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *CreateConfigResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *CreateConfigResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+type UpdateConfigRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId    string        `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	ConfigDetail *ConfigDetail `protobuf:"bytes,2,opt,name=config_detail,json=configDetail,proto3" json:"config_detail,omitempty"`
+}
+
+func (x *UpdateConfigRequest) Reset() {
+	*x = UpdateConfigRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[15]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UpdateConfigRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateConfigRequest) ProtoMessage() {}
+
+func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[15]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateConfigRequest.ProtoReflect.Descriptor instead.
+func (*UpdateConfigRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{15}
+}
+
+func (x *UpdateConfigRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *UpdateConfigRequest) GetConfigDetail() *ConfigDetail {
+	if x != nil {
+		return x.ConfigDetail
+	}
+	return nil
+}
+
+type UpdateConfigResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *UpdateConfigResponse) Reset() {
+	*x = UpdateConfigResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[16]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UpdateConfigResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateConfigResponse) ProtoMessage() {}
+
+func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[16]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateConfigResponse.ProtoReflect.Descriptor instead.
+func (*UpdateConfigResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{16}
+}
+
+func (x *UpdateConfigResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *UpdateConfigResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *UpdateConfigResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+type DeleteConfigRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId  string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	ConfigName string `protobuf:"bytes,2,opt,name=config_name,json=configName,proto3" json:"config_name,omitempty"`
+}
+
+func (x *DeleteConfigRequest) Reset() {
+	*x = DeleteConfigRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[17]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DeleteConfigRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteConfigRequest) ProtoMessage() {}
+
+func (x *DeleteConfigRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[17]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteConfigRequest.ProtoReflect.Descriptor instead.
+func (*DeleteConfigRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{17}
+}
+
+func (x *DeleteConfigRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *DeleteConfigRequest) GetConfigName() string {
+	if x != nil {
+		return x.ConfigName
+	}
+	return ""
+}
+
+type DeleteConfigResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *DeleteConfigResponse) Reset() {
+	*x = DeleteConfigResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[18]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DeleteConfigResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeleteConfigResponse) ProtoMessage() {}
+
+func (x *DeleteConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[18]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeleteConfigResponse.ProtoReflect.Descriptor instead.
+func (*DeleteConfigResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{18}
+}
+
+func (x *DeleteConfigResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *DeleteConfigResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *DeleteConfigResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+type GetConfigRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId  string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	ConfigName string `protobuf:"bytes,2,opt,name=config_name,json=configName,proto3" json:"config_name,omitempty"`
+}
+
+func (x *GetConfigRequest) Reset() {
+	*x = GetConfigRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[19]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetConfigRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetConfigRequest) ProtoMessage() {}
+
+func (x *GetConfigRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[19]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetConfigRequest.ProtoReflect.Descriptor instead.
+func (*GetConfigRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{19}
+}
+
+func (x *GetConfigRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *GetConfigRequest) GetConfigName() string {
+	if x != nil {
+		return x.ConfigName
+	}
+	return ""
+}
+
+type GetConfigResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId   string        `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code         RespCode      `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message      string        `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	ConfigDetail *ConfigDetail `protobuf:"bytes,4,opt,name=config_detail,json=configDetail,proto3" json:"config_detail,omitempty"`
+}
+
+func (x *GetConfigResponse) Reset() {
+	*x = GetConfigResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[20]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetConfigResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetConfigResponse) ProtoMessage() {}
+
+func (x *GetConfigResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[20]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetConfigResponse.ProtoReflect.Descriptor instead.
+func (*GetConfigResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{20}
+}
+
+func (x *GetConfigResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *GetConfigResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *GetConfigResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *GetConfigResponse) GetConfigDetail() *ConfigDetail {
+	if x != nil {
+		return x.ConfigDetail
+	}
+	return nil
+}
+
+type ListConfigsRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+}
+
+func (x *ListConfigsRequest) Reset() {
+	*x = ListConfigsRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[21]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListConfigsRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListConfigsRequest) ProtoMessage() {}
+
+func (x *ListConfigsRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[21]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListConfigsRequest.ProtoReflect.Descriptor instead.
+func (*ListConfigsRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{21}
+}
+
+func (x *ListConfigsRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+type ListConfigsResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId    string          `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code          RespCode        `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message       string          `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	ConfigDetails []*ConfigDetail `protobuf:"bytes,4,rep,name=config_details,json=configDetails,proto3" json:"config_details,omitempty"`
+}
+
+func (x *ListConfigsResponse) Reset() {
+	*x = ListConfigsResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[22]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListConfigsResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListConfigsResponse) ProtoMessage() {}
+
+func (x *ListConfigsResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[22]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListConfigsResponse.ProtoReflect.Descriptor instead.
+func (*ListConfigsResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{22}
+}
+
+func (x *ListConfigsResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *ListConfigsResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *ListConfigsResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *ListConfigsResponse) GetConfigDetails() []*ConfigDetail {
+	if x != nil {
+		return x.ConfigDetails
+	}
+	return nil
+}
+
+type ApplyConfigToAgentGroupRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId  string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	ConfigName string `protobuf:"bytes,2,opt,name=config_name,json=configName,proto3" json:"config_name,omitempty"`
+	GroupName  string `protobuf:"bytes,3,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
+}
+
+func (x *ApplyConfigToAgentGroupRequest) Reset() {
+	*x = ApplyConfigToAgentGroupRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[23]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ApplyConfigToAgentGroupRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ApplyConfigToAgentGroupRequest) ProtoMessage() {}
+
+func (x *ApplyConfigToAgentGroupRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[23]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ApplyConfigToAgentGroupRequest.ProtoReflect.Descriptor instead.
+func (*ApplyConfigToAgentGroupRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{23}
+}
+
+func (x *ApplyConfigToAgentGroupRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *ApplyConfigToAgentGroupRequest) GetConfigName() string {
+	if x != nil {
+		return x.ConfigName
+	}
+	return ""
+}
+
+func (x *ApplyConfigToAgentGroupRequest) GetGroupName() string {
+	if x != nil {
+		return x.GroupName
+	}
+	return ""
+}
+
+type ApplyConfigToAgentGroupResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *ApplyConfigToAgentGroupResponse) Reset() {
+	*x = ApplyConfigToAgentGroupResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[24]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ApplyConfigToAgentGroupResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ApplyConfigToAgentGroupResponse) ProtoMessage() {}
+
+func (x *ApplyConfigToAgentGroupResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[24]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ApplyConfigToAgentGroupResponse.ProtoReflect.Descriptor instead.
+func (*ApplyConfigToAgentGroupResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{24}
+}
+
+func (x *ApplyConfigToAgentGroupResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *ApplyConfigToAgentGroupResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *ApplyConfigToAgentGroupResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+type RemoveConfigFromAgentGroupRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId  string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	ConfigName string `protobuf:"bytes,2,opt,name=config_name,json=configName,proto3" json:"config_name,omitempty"`
+	GroupName  string `protobuf:"bytes,3,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
+}
+
+func (x *RemoveConfigFromAgentGroupRequest) Reset() {
+	*x = RemoveConfigFromAgentGroupRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[25]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RemoveConfigFromAgentGroupRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RemoveConfigFromAgentGroupRequest) ProtoMessage() {}
+
+func (x *RemoveConfigFromAgentGroupRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[25]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RemoveConfigFromAgentGroupRequest.ProtoReflect.Descriptor instead.
+func (*RemoveConfigFromAgentGroupRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{25}
+}
+
+func (x *RemoveConfigFromAgentGroupRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *RemoveConfigFromAgentGroupRequest) GetConfigName() string {
+	if x != nil {
+		return x.ConfigName
+	}
+	return ""
+}
+
+func (x *RemoveConfigFromAgentGroupRequest) GetGroupName() string {
+	if x != nil {
+		return x.GroupName
+	}
+	return ""
+}
+
+type RemoveConfigFromAgentGroupResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *RemoveConfigFromAgentGroupResponse) Reset() {
+	*x = RemoveConfigFromAgentGroupResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[26]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RemoveConfigFromAgentGroupResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RemoveConfigFromAgentGroupResponse) ProtoMessage() {}
+
+func (x *RemoveConfigFromAgentGroupResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[26]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RemoveConfigFromAgentGroupResponse.ProtoReflect.Descriptor instead.
+func (*RemoveConfigFromAgentGroupResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{26}
+}
+
+func (x *RemoveConfigFromAgentGroupResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *RemoveConfigFromAgentGroupResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *RemoveConfigFromAgentGroupResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+type GetAppliedConfigsForAgentGroupRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
+}
+
+func (x *GetAppliedConfigsForAgentGroupRequest) Reset() {
+	*x = GetAppliedConfigsForAgentGroupRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[27]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetAppliedConfigsForAgentGroupRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAppliedConfigsForAgentGroupRequest) ProtoMessage() {}
+
+func (x *GetAppliedConfigsForAgentGroupRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[27]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAppliedConfigsForAgentGroupRequest.ProtoReflect.Descriptor instead.
+func (*GetAppliedConfigsForAgentGroupRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{27}
+}
+
+func (x *GetAppliedConfigsForAgentGroupRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *GetAppliedConfigsForAgentGroupRequest) GetGroupName() string {
+	if x != nil {
+		return x.GroupName
+	}
+	return ""
+}
+
+type GetAppliedConfigsForAgentGroupResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId  string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code        RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message     string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	ConfigNames []string `protobuf:"bytes,4,rep,name=config_names,json=configNames,proto3" json:"config_names,omitempty"`
+}
+
+func (x *GetAppliedConfigsForAgentGroupResponse) Reset() {
+	*x = GetAppliedConfigsForAgentGroupResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[28]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetAppliedConfigsForAgentGroupResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAppliedConfigsForAgentGroupResponse) ProtoMessage() {}
+
+func (x *GetAppliedConfigsForAgentGroupResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[28]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAppliedConfigsForAgentGroupResponse.ProtoReflect.Descriptor instead.
+func (*GetAppliedConfigsForAgentGroupResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{28}
+}
+
+func (x *GetAppliedConfigsForAgentGroupResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *GetAppliedConfigsForAgentGroupResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *GetAppliedConfigsForAgentGroupResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *GetAppliedConfigsForAgentGroupResponse) GetConfigNames() []string {
+	if x != nil {
+		return x.ConfigNames
+	}
+	return nil
+}
+
+type GetAppliedAgentGroupsRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId  string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	ConfigName string `protobuf:"bytes,2,opt,name=config_name,json=configName,proto3" json:"config_name,omitempty"`
+}
+
+func (x *GetAppliedAgentGroupsRequest) Reset() {
+	*x = GetAppliedAgentGroupsRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[29]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetAppliedAgentGroupsRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAppliedAgentGroupsRequest) ProtoMessage() {}
+
+func (x *GetAppliedAgentGroupsRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[29]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAppliedAgentGroupsRequest.ProtoReflect.Descriptor instead.
+func (*GetAppliedAgentGroupsRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{29}
+}
+
+func (x *GetAppliedAgentGroupsRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *GetAppliedAgentGroupsRequest) GetConfigName() string {
+	if x != nil {
+		return x.ConfigName
+	}
+	return ""
+}
+
+type GetAppliedAgentGroupsResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId      string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code            RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message         string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	AgentGroupNames []string `protobuf:"bytes,4,rep,name=agent_group_names,json=agentGroupNames,proto3" json:"agent_group_names,omitempty"`
+}
+
+func (x *GetAppliedAgentGroupsResponse) Reset() {
+	*x = GetAppliedAgentGroupsResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[30]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetAppliedAgentGroupsResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAppliedAgentGroupsResponse) ProtoMessage() {}
+
+func (x *GetAppliedAgentGroupsResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[30]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAppliedAgentGroupsResponse.ProtoReflect.Descriptor instead.
+func (*GetAppliedAgentGroupsResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{30}
+}
+
+func (x *GetAppliedAgentGroupsResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *GetAppliedAgentGroupsResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *GetAppliedAgentGroupsResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *GetAppliedAgentGroupsResponse) GetAgentGroupNames() []string {
+	if x != nil {
+		return x.AgentGroupNames
+	}
+	return nil
+}
+
+type ListAgentsRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
+	GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"`
+}
+
+func (x *ListAgentsRequest) Reset() {
+	*x = ListAgentsRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[31]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListAgentsRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListAgentsRequest) ProtoMessage() {}
+
+func (x *ListAgentsRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[31]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListAgentsRequest.ProtoReflect.Descriptor instead.
+func (*ListAgentsRequest) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{31}
+}
+
+func (x *ListAgentsRequest) GetRequestId() string {
+	if x != nil {
+		return x.RequestId
+	}
+	return ""
+}
+
+func (x *ListAgentsRequest) GetGroupName() string {
+	if x != nil {
+		return x.GroupName
+	}
+	return ""
+}
+
+type ListAgentsResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResponseId string   `protobuf:"bytes,1,opt,name=response_id,json=responseId,proto3" json:"response_id,omitempty"`
+	Code       RespCode `protobuf:"varint,2,opt,name=code,proto3,enum=configserver.proto.RespCode" json:"code,omitempty"`
+	Message    string   `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+	Agents     []*Agent `protobuf:"bytes,4,rep,name=agents,proto3" json:"agents,omitempty"`
+}
+
+func (x *ListAgentsResponse) Reset() {
+	*x = ListAgentsResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_user_proto_msgTypes[32]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListAgentsResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListAgentsResponse) ProtoMessage() {}
+
+func (x *ListAgentsResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_user_proto_msgTypes[32]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListAgentsResponse.ProtoReflect.Descriptor instead.
+func (*ListAgentsResponse) Descriptor() ([]byte, []int) {
+	return file_user_proto_rawDescGZIP(), []int{32}
+}
+
+func (x *ListAgentsResponse) GetResponseId() string {
+	if x != nil {
+		return x.ResponseId
+	}
+	return ""
+}
+
+func (x *ListAgentsResponse) GetCode() RespCode {
+	if x != nil {
+		return x.Code
+	}
+	return RespCode_ACCEPT
+}
+
+func (x *ListAgentsResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *ListAgentsResponse) GetAgents() []*Agent {
+	if x != nil {
+		return x.Agents
+	}
+	return nil
+}
+
+var File_user_proto protoreflect.FileDescriptor
+
+var file_user_proto_rawDesc = []byte{
+	0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x1a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x39, 0x0a,
+	0x0d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x12, 0x12,
+	0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x84, 0x01, 0x0a, 0x0a, 0x41, 0x67, 0x65,
+	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70,
+	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f,
+	0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,
+	0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73,
+	0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73,
+	0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e,
+	0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x54, 0x61, 0x67, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x22,
+	0x80, 0x02, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x67, 0x65,
+	0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65,
+	0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79,
+	0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x54,
+	0x79, 0x70, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+	0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65,
+	0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x61, 0x74,
+	0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73,
+	0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x25, 0x0a, 0x0e,
+	0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x74,
+	0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74,
+	0x75, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76,
+	0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76,
+	0x61, 0x6c, 0x22, 0x79, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e,
+	0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
+	0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x3f, 0x0a, 0x0b,
+	0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x87, 0x01,
+	0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f,
+	0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63,
+	0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52,
+	0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a,
+	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x79, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74,
+	0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49,
+	0x64, 0x12, 0x3f, 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73,
+	0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e,
+	0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f,
+	0x75, 0x70, 0x22, 0x87, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65,
+	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64,
+	0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c,
+	0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f,
+	0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x57, 0x0a, 0x17,
+	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f,
+	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75,
+	0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+	0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52,
+	0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22,
+	0x54, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f,
+	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75,
+	0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xc5, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65,
+	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64,
+	0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c,
+	0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f,
+	0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3f, 0x0a, 0x0b,
+	0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x37, 0x0a,
+	0x16, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0xc9, 0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x41,
+	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52,
+	0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
+	0x41, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18,
+	0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65,
+	0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74,
+	0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x73, 0x22, 0x7b, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22,
+	0x83, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73,
+	0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x7b, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x0d, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65,
+	0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65,
+	0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
+	0x69, 0x6c, 0x22, 0x83, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04,
+	0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+	0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18,
+	0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x55, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65,
+	0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f,
+	0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22,
+	0x83, 0x01, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73,
+	0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x52, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xc7, 0x01, 0x0a, 0x11, 0x47, 0x65,
+	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64,
+	0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c,
+	0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f,
+	0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x45, 0x0a, 0x0d,
+	0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76,
+	0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44,
+	0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74,
+	0x61, 0x69, 0x6c, 0x22, 0x33, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0xcb, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73,
+	0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49,
+	0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
+	0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63,
+	0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x47, 0x0a,
+	0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18,
+	0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65,
+	0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44,
+	0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x7f, 0x0a, 0x1e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75,
+	0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72,
+	0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x8e, 0x01, 0x0a, 0x1f, 0x41, 0x70, 0x70, 0x6c,
+	0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x6f, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
+	0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04,
+	0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+	0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18,
+	0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x21, 0x52, 0x65, 0x6d,
+	0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x67, 0x65,
+	0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
+	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a,
+	0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d,
+	0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x91, 0x01,
+	0x0a, 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x72,
+	0x6f, 0x6d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76,
+	0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64,
+	0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
+	0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x22, 0x65, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x46, 0x6f, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72,
+	0x6f, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
+	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f,
+	0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67,
+	0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x26, 0x47, 0x65, 0x74,
+	0x41, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x46, 0x6f,
+	0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65,
+	0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f, 0x64, 0x65,
+	0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73,
+	0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e, 0x61,
+	0x6d, 0x65, 0x73, 0x22, 0x5e, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65,
+	0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4e,
+	0x61, 0x6d, 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69,
+	0x65, 0x64, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72,
+	0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x43, 0x6f,
+	0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
+	0x67, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75,
+	0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x61,
+	0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x51,
+	0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d,
+	0x65, 0x22, 0xb4, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x73,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73,
+	0x70, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x18,
+	0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x65,
+	0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74,
+	0x52, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x16, 0x5a, 0x14, 0x2e, 0x3b, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_user_proto_rawDescOnce sync.Once
+	file_user_proto_rawDescData = file_user_proto_rawDesc
+)
+
+func file_user_proto_rawDescGZIP() []byte {
+	file_user_proto_rawDescOnce.Do(func() {
+		file_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_user_proto_rawDescData)
+	})
+	return file_user_proto_rawDescData
+}
+
+var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 33)
+var file_user_proto_goTypes = []interface{}{
+	(*AgentGroupTag)(nil),                          // 0: configserver.proto.AgentGroupTag
+	(*AgentGroup)(nil),                             // 1: configserver.proto.AgentGroup
+	(*Agent)(nil),                                  // 2: configserver.proto.Agent
+	(*CreateAgentGroupRequest)(nil),                // 3: configserver.proto.CreateAgentGroupRequest
+	(*CreateAgentGroupResponse)(nil),               // 4: configserver.proto.CreateAgentGroupResponse
+	(*UpdateAgentGroupRequest)(nil),                // 5: configserver.proto.UpdateAgentGroupRequest
+	(*UpdateAgentGroupResponse)(nil),               // 6: configserver.proto.UpdateAgentGroupResponse
+	(*DeleteAgentGroupRequest)(nil),                // 7: configserver.proto.DeleteAgentGroupRequest
+	(*DeleteAgentGroupResponse)(nil),               // 8: configserver.proto.DeleteAgentGroupResponse
+	(*GetAgentGroupRequest)(nil),                   // 9: configserver.proto.GetAgentGroupRequest
+	(*GetAgentGroupResponse)(nil),                  // 10: configserver.proto.GetAgentGroupResponse
+	(*ListAgentGroupsRequest)(nil),                 // 11: configserver.proto.ListAgentGroupsRequest
+	(*ListAgentGroupsResponse)(nil),                // 12: configserver.proto.ListAgentGroupsResponse
+	(*CreateConfigRequest)(nil),                    // 13: configserver.proto.CreateConfigRequest
+	(*CreateConfigResponse)(nil),                   // 14: configserver.proto.CreateConfigResponse
+	(*UpdateConfigRequest)(nil),                    // 15: configserver.proto.UpdateConfigRequest
+	(*UpdateConfigResponse)(nil),                   // 16: configserver.proto.UpdateConfigResponse
+	(*DeleteConfigRequest)(nil),                    // 17: configserver.proto.DeleteConfigRequest
+	(*DeleteConfigResponse)(nil),                   // 18: configserver.proto.DeleteConfigResponse
+	(*GetConfigRequest)(nil),                       // 19: configserver.proto.GetConfigRequest
+	(*GetConfigResponse)(nil),                      // 20: configserver.proto.GetConfigResponse
+	(*ListConfigsRequest)(nil),                     // 21: configserver.proto.ListConfigsRequest
+	(*ListConfigsResponse)(nil),                    // 22: configserver.proto.ListConfigsResponse
+	(*ApplyConfigToAgentGroupRequest)(nil),         // 23: configserver.proto.ApplyConfigToAgentGroupRequest
+	(*ApplyConfigToAgentGroupResponse)(nil),        // 24: configserver.proto.ApplyConfigToAgentGroupResponse
+	(*RemoveConfigFromAgentGroupRequest)(nil),      // 25: configserver.proto.RemoveConfigFromAgentGroupRequest
+	(*RemoveConfigFromAgentGroupResponse)(nil),     // 26: configserver.proto.RemoveConfigFromAgentGroupResponse
+	(*GetAppliedConfigsForAgentGroupRequest)(nil),  // 27: configserver.proto.GetAppliedConfigsForAgentGroupRequest
+	(*GetAppliedConfigsForAgentGroupResponse)(nil), // 28: configserver.proto.GetAppliedConfigsForAgentGroupResponse
+	(*GetAppliedAgentGroupsRequest)(nil),           // 29: configserver.proto.GetAppliedAgentGroupsRequest
+	(*GetAppliedAgentGroupsResponse)(nil),          // 30: configserver.proto.GetAppliedAgentGroupsResponse
+	(*ListAgentsRequest)(nil),                      // 31: configserver.proto.ListAgentsRequest
+	(*ListAgentsResponse)(nil),                     // 32: configserver.proto.ListAgentsResponse
+	(*AgentAttributes)(nil),                        // 33: configserver.proto.AgentAttributes
+	(RespCode)(0),                                  // 34: configserver.proto.RespCode
+	(*ConfigDetail)(nil),                           // 35: configserver.proto.ConfigDetail
+}
+var file_user_proto_depIdxs = []int32{
+	0,  // 0: configserver.proto.AgentGroup.tags:type_name -> configserver.proto.AgentGroupTag
+	33, // 1: configserver.proto.Agent.attributes:type_name -> configserver.proto.AgentAttributes
+	1,  // 2: configserver.proto.CreateAgentGroupRequest.agent_group:type_name -> configserver.proto.AgentGroup
+	34, // 3: configserver.proto.CreateAgentGroupResponse.code:type_name -> configserver.proto.RespCode
+	1,  // 4: configserver.proto.UpdateAgentGroupRequest.agent_group:type_name -> configserver.proto.AgentGroup
+	34, // 5: configserver.proto.UpdateAgentGroupResponse.code:type_name -> configserver.proto.RespCode
+	34, // 6: configserver.proto.DeleteAgentGroupResponse.code:type_name -> configserver.proto.RespCode
+	34, // 7: configserver.proto.GetAgentGroupResponse.code:type_name -> configserver.proto.RespCode
+	1,  // 8: configserver.proto.GetAgentGroupResponse.agent_group:type_name -> configserver.proto.AgentGroup
+	34, // 9: configserver.proto.ListAgentGroupsResponse.code:type_name -> configserver.proto.RespCode
+	1,  // 10: configserver.proto.ListAgentGroupsResponse.agent_groups:type_name -> configserver.proto.AgentGroup
+	35, // 11: configserver.proto.CreateConfigRequest.config_detail:type_name -> configserver.proto.ConfigDetail
+	34, // 12: configserver.proto.CreateConfigResponse.code:type_name -> configserver.proto.RespCode
+	35, // 13: configserver.proto.UpdateConfigRequest.config_detail:type_name -> configserver.proto.ConfigDetail
+	34, // 14: configserver.proto.UpdateConfigResponse.code:type_name -> configserver.proto.RespCode
+	34, // 15: configserver.proto.DeleteConfigResponse.code:type_name -> configserver.proto.RespCode
+	34, // 16: configserver.proto.GetConfigResponse.code:type_name -> configserver.proto.RespCode
+	35, // 17: configserver.proto.GetConfigResponse.config_detail:type_name -> configserver.proto.ConfigDetail
+	34, // 18: configserver.proto.ListConfigsResponse.code:type_name -> configserver.proto.RespCode
+	35, // 19: configserver.proto.ListConfigsResponse.config_details:type_name -> configserver.proto.ConfigDetail
+	34, // 20: configserver.proto.ApplyConfigToAgentGroupResponse.code:type_name -> configserver.proto.RespCode
+	34, // 21: configserver.proto.RemoveConfigFromAgentGroupResponse.code:type_name -> configserver.proto.RespCode
+	34, // 22: configserver.proto.GetAppliedConfigsForAgentGroupResponse.code:type_name -> configserver.proto.RespCode
+	34, // 23: configserver.proto.GetAppliedAgentGroupsResponse.code:type_name -> configserver.proto.RespCode
+	34, // 24: configserver.proto.ListAgentsResponse.code:type_name -> configserver.proto.RespCode
+	2,  // 25: configserver.proto.ListAgentsResponse.agents:type_name -> configserver.proto.Agent
+	26, // [26:26] is the sub-list for method output_type
+	26, // [26:26] is the sub-list for method input_type
+	26, // [26:26] is the sub-list for extension type_name
+	26, // [26:26] is the sub-list for extension extendee
+	0,  // [0:26] is the sub-list for field type_name
+}
+
+func init() { file_user_proto_init() }
+func file_user_proto_init() {
+	if File_user_proto != nil {
+		return
+	}
+	file_agent_proto_init()
+	if !protoimpl.UnsafeEnabled {
+		file_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AgentGroupTag); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AgentGroup); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Agent); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateAgentGroupRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateAgentGroupResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateAgentGroupRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateAgentGroupResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteAgentGroupRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteAgentGroupResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetAgentGroupRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetAgentGroupResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListAgentGroupsRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListAgentGroupsResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateConfigRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateConfigResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateConfigRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateConfigResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteConfigRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DeleteConfigResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetConfigRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetConfigResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListConfigsRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListConfigsResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ApplyConfigToAgentGroupRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ApplyConfigToAgentGroupResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RemoveConfigFromAgentGroupRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RemoveConfigFromAgentGroupResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetAppliedConfigsForAgentGroupRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetAppliedConfigsForAgentGroupResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetAppliedAgentGroupsRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetAppliedAgentGroupsResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListAgentsRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_user_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListAgentsResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_user_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   33,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_user_proto_goTypes,
+		DependencyIndexes: file_user_proto_depIdxs,
+		MessageInfos:      file_user_proto_msgTypes,
+	}.Build()
+	File_user_proto = out.File
+	file_user_proto_rawDesc = nil
+	file_user_proto_goTypes = nil
+	file_user_proto_depIdxs = nil
+}
diff --git a/config_server/v1/service/router/router.go b/config_server/v1/service/router/router.go
new file mode 100644
index 0000000000..c01fde50e5
--- /dev/null
+++ b/config_server/v1/service/router/router.go
@@ -0,0 +1,68 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package router
+
+import (
+	"github.com/gin-gonic/gin"
+
+	"config-server/interface/agent"
+	"config-server/interface/user"
+	"config-server/setting"
+)
+
+func InitRouter() {
+	router := gin.Default()
+
+	InitUserRouter(router)
+	InitAgentRouter(router)
+
+	err := router.Run(setting.GetSetting().IP + ":" + setting.GetSetting().Port)
+	if err != nil {
+		panic(err)
+	}
+}
+
+func InitUserRouter(router *gin.Engine) {
+	userGroup := router.Group("/User")
+	{
+		userGroup.POST("/CreateAgentGroup", user.CreateAgentGroup)
+		userGroup.PUT("/UpdateAgentGroup", user.UpdateAgentGroup)
+		userGroup.DELETE("/DeleteAgentGroup", user.DeleteAgentGroup)
+		userGroup.POST("/GetAgentGroup", user.GetAgentGroup)
+		userGroup.POST("/ListAgentGroups", user.ListAgentGroups)
+
+		userGroup.POST("/CreateConfig", user.CreateConfig)
+		userGroup.PUT("/UpdateConfig", user.UpdateConfig)
+		userGroup.DELETE("/DeleteConfig", user.DeleteConfig)
+		userGroup.POST("/GetConfig", user.GetConfig)
+		userGroup.POST("/ListConfigs", user.ListConfigs)
+
+		userGroup.PUT("/ApplyConfigToAgentGroup", user.ApplyConfigToAgentGroup)
+		userGroup.DELETE("/RemoveConfigFromAgentGroup", user.RemoveConfigFromAgentGroup)
+		userGroup.POST("/GetAppliedConfigsForAgentGroup", user.GetAppliedConfigsForAgentGroup)
+		userGroup.POST("/GetAppliedAgentGroups", user.GetAppliedAgentGroups)
+		userGroup.POST("/ListAgents", user.ListAgents)
+	}
+}
+
+func InitAgentRouter(router *gin.Engine) {
+	agentGroup := router.Group("/Agent")
+	{
+		agentGroup.POST("/HeartBeat", agent.HeartBeat)
+
+		agentGroup.POST("/FetchPipelineConfig", agent.FetchPipelineConfig)
+		agentGroup.POST("/FetchAgentConfig", agent.FetchAgentConfig)
+	}
+}
diff --git a/config_server/v1/service/service.go b/config_server/v1/service/service.go
new file mode 100644
index 0000000000..3b2541a95a
--- /dev/null
+++ b/config_server/v1/service/service.go
@@ -0,0 +1,25 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+	"config-server/router"
+	"config-server/store"
+)
+
+func main() {
+	defer store.GetStore().Close()
+	router.InitRouter()
+}
diff --git a/config_server/v1/service/setting/mysql-setting.json b/config_server/v1/service/setting/mysql-setting.json
new file mode 100644
index 0000000000..233e2c4eb7
--- /dev/null
+++ b/config_server/v1/service/setting/mysql-setting.json
@@ -0,0 +1,11 @@
+{
+    "ip":"127.0.0.1",
+    "store_mode": "gorm",
+    "port": "8899",
+    "db_path": "./DB",
+    "driver": "mysql",
+    "dsn": "ilogtail:123456@tcp(127.0.0.1:3306)/ilogtail_config_server?charset=utf8&parseTime=True&loc=Local",
+    "auto_migrate_schema": true,
+    "agent_update_interval": 1,
+    "config_sync_interval": 3
+}
diff --git a/config_server/v1/service/setting/setting.go b/config_server/v1/service/setting/setting.go
new file mode 100644
index 0000000000..20f779eda4
--- /dev/null
+++ b/config_server/v1/service/setting/setting.go
@@ -0,0 +1,104 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package setting
+
+import (
+	"log"
+	"reflect"
+
+	"config-server/common"
+)
+
+type Setting struct {
+	IP                  string `json:"ip"`                    // default: "127.0.0.1"
+	StoreMode           string `json:"store_mode"`            // support "leveldb", "gorm"
+	Port                string `json:"port"`                  // default: "8899"
+	DbPath              string `json:"db_path"`               // default: "./DB"
+	Driver              string `json:"driver"`                // support "mysql", "postgre", "sqlite", "sqlserver"
+	Dsn                 string `json:"dsn"`                   // gorm dsn
+	AutoMigrateSchema   bool   `json:"auto_migrate_schema"`   // auto migrate schema
+	AgentUpdateInterval int    `json:"agent_update_interval"` // default: 1s
+	ConfigSyncInterval  int    `json:"config_sync_interval"`  // default: 3s
+}
+
+var mySetting *Setting
+
+var settingFile = "./setting/setting.json"
+
+/*
+Create a singleton of setting
+*/
+func GetSetting() Setting {
+	return *mySetting
+}
+
+/*
+Use map to update setting.
+For example, if the value of map is {store_mode:"mysql"},
+this function will change "mySetting's StoreMode" to "mysql".
+*/
+func UpdateSetting(tagMap map[string]interface{}) {
+	v := reflect.ValueOf(mySetting).Elem()
+	t := v.Type()
+
+	fieldNum := v.NumField()
+	for i := 0; i < fieldNum; i++ {
+		fieldInfo := t.Field(i)
+		tag := fieldInfo.Tag.Get("json")
+		if tag == "" {
+			continue
+		}
+		if value, ok := tagMap[tag]; ok {
+			if reflect.ValueOf(value).Type() == v.FieldByName(fieldInfo.Name).Type() {
+				v.FieldByName(fieldInfo.Name).Set(reflect.ValueOf(value))
+			}
+		}
+	}
+	err := common.WriteJSON(settingFile, mySetting)
+	if err != nil {
+		log.Println(err.Error())
+	}
+}
+
+func init() {
+	mySetting = new(Setting)
+	err := common.ReadJSON(settingFile, mySetting)
+	if err != nil {
+		panic(err)
+	}
+	if mySetting.IP == "" {
+		mySetting.IP = "127.0.0.1"
+	}
+	if mySetting.Port == "" {
+		mySetting.Port = "8899"
+	}
+	if mySetting.StoreMode == "" {
+		panic("Please set store mode")
+	}
+	if mySetting.StoreMode == "gorm" {
+		if mySetting.Driver == "" {
+			panic("Please set driver")
+		}
+		if mySetting.Dsn == "" {
+			panic("Please set dsn")
+		}
+	}
+	if mySetting.AgentUpdateInterval == 0 {
+		mySetting.AgentUpdateInterval = 1
+	}
+	if mySetting.ConfigSyncInterval == 0 {
+		mySetting.ConfigSyncInterval = 3
+	}
+}
diff --git a/config_server/v1/service/setting/setting.json b/config_server/v1/service/setting/setting.json
new file mode 100644
index 0000000000..cea005fc54
--- /dev/null
+++ b/config_server/v1/service/setting/setting.json
@@ -0,0 +1,8 @@
+{
+    "ip":"127.0.0.1",
+    "store_mode": "leveldb",
+    "port": "8899",
+    "db_path": "./DB",
+    "agent_update_interval": 1,
+    "config_sync_interval": 3
+}
\ No newline at end of file
diff --git a/config_server/v1/service/setting/sqlite-setting.json b/config_server/v1/service/setting/sqlite-setting.json
new file mode 100644
index 0000000000..981d45821a
--- /dev/null
+++ b/config_server/v1/service/setting/sqlite-setting.json
@@ -0,0 +1,10 @@
+{
+    "ip":"127.0.0.1",
+    "store_mode": "gorm",
+    "port": "8899",
+    "driver": "sqlite",
+    "dsn": "sqlite.db",
+    "auto_migrate_schema": true,
+    "agent_update_interval": 1,
+    "config_sync_interval": 3
+}
diff --git a/config_server/v1/service/store/gorm/gorm.go b/config_server/v1/service/store/gorm/gorm.go
new file mode 100644
index 0000000000..b0145b60c7
--- /dev/null
+++ b/config_server/v1/service/store/gorm/gorm.go
@@ -0,0 +1,273 @@
+// Copyright 2024 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package gorm
+
+import (
+	"errors"
+	"fmt"
+	"log"
+	"os"
+	"reflect"
+	"regexp"
+	"strings"
+	"time"
+
+	"config-server/model"
+	"config-server/setting"
+	database "config-server/store/interface_database"
+
+	"gorm.io/driver/mysql"
+	"gorm.io/driver/postgres"
+	"gorm.io/driver/sqlite"
+	"gorm.io/driver/sqlserver"
+	"gorm.io/gorm"
+	"gorm.io/gorm/logger"
+)
+
+type Store struct {
+	db *gorm.DB
+}
+
+func (s *Store) Connect() error {
+	slowLogger := logger.New(
+		log.New(os.Stdout, "\r\n", log.LstdFlags),
+		logger.Config{
+			SlowThreshold:             1 * time.Second,
+			LogLevel:                  logger.Warn,
+			IgnoreRecordNotFoundError: true,
+			Colorful:                  true,
+		},
+	)
+	option := gorm.Config{
+		Logger: slowLogger,
+	}
+	var db *gorm.DB
+	var err error
+	driver := setting.GetSetting().Driver
+	dsn := setting.GetSetting().Dsn
+	switch driver {
+	case "mysql":
+		db, err = gorm.Open(mysql.Open(dsn), &option)
+	case "postgre":
+		db, err = gorm.Open(postgres.Open(dsn), &option)
+	case "sqlite":
+		db, err = gorm.Open(sqlite.Open(dsn), &option)
+	case "sqlserver":
+		db, err = gorm.Open(sqlserver.Open(dsn), &option)
+	default:
+		return errors.New("wrong gorm driver: " + driver)
+	}
+	if err != nil {
+		return err
+	}
+	if setting.GetSetting().AutoMigrateSchema {
+		db.AutoMigrate(&model.AgentGroup{}, &model.ConfigDetail{}, &model.Agent{})
+	}
+	s.db = db
+	return nil
+}
+
+func (s *Store) GetMode() string {
+	return "gorm"
+}
+
+func (s *Store) Close() error {
+	db, err := s.db.DB()
+	if err != nil {
+		return err
+	}
+	return db.Close()
+}
+
+func (s *Store) Get(table string, entityKey string) (interface{}, error) {
+	model, pk, err := initModelAndPrimaryKey(table)
+	if err != nil {
+		return nil, err
+	}
+	err = s.db.Table(table).Where(fmt.Sprintf("%s = ?", pk), entityKey).Take(&model).Error
+	if err != nil {
+		return nil, err
+	}
+	return model, nil
+}
+
+func (s *Store) Add(table string, entityKey string, entity interface{}) error {
+	err := s.db.Table(table).Create(entity).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (s *Store) Update(table string, entityKey string, entity interface{}) error {
+	err := s.db.Table(table).Save(entity).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (s *Store) Has(table string, entityKey string) (bool, error) {
+	_, pk, err := initModelAndPrimaryKey(table)
+	if err != nil {
+		return false, err
+	}
+	var count int64
+	err = s.db.Table(table).Where(fmt.Sprintf("%s = ?", pk), entityKey).Limit(1).Count(&count).Error
+	if err != nil {
+		return false, err
+	}
+	return count > 0, nil
+}
+
+func (s *Store) Delete(table string, entityKey string) error {
+	_, pk, err := initModelAndPrimaryKey(table)
+	if err != nil {
+		return err
+	}
+	err = s.db.Table(table).Where(fmt.Sprintf("%s = ?", pk), entityKey).Delete(nil).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (s *Store) GetAll(table string) ([]interface{}, error) {
+	return s.GetWithPairs(table)
+}
+
+func (s *Store) GetWithPairs(table string, pairs ...interface{}) ([]interface{}, error) {
+	if len(pairs)%2 != 0 {
+		return nil, errors.New("params must be in pairs")
+	}
+
+	objectType, ok := model.ModelTypes[table]
+	if !ok {
+		return nil, errors.New("unsupported table: " + table)
+	}
+
+	objectsType := reflect.SliceOf(objectType.Elem())
+	objects := reflect.New(objectsType)
+
+	db := s.db.Table(table)
+	for i := 0; i < len(pairs); i += 2 {
+		column := camelCaseToSnakeCase(fmt.Sprintf("%v", pairs[i]))
+		value := pairs[i+1]
+		db = db.Where(fmt.Sprintf("%s = ?", column), value)
+	}
+
+	err := db.Find(objects.Interface()).Error
+	if err != nil {
+		return nil, err
+	}
+
+	objects = objects.Elem()
+
+	result := make([]interface{}, objects.Len())
+	for i := 0; i < objects.Len(); i++ {
+		result[i] = objects.Index(i).Interface()
+	}
+	return result, nil
+}
+
+func (s *Store) Count(table string) (int, error) {
+	var count int64
+	err := s.db.Table(table).Count(&count).Error
+	if err != nil {
+		return 0, err
+	}
+	return int(count), nil
+}
+
+func (s *Store) WriteBatch(batch *database.Batch) error {
+	tx := s.db.Begin()
+
+	for !batch.Empty() {
+		data := batch.Pop()
+		_, pk, err := initModelAndPrimaryKey(data.Table)
+		if err != nil {
+			tx.Rollback()
+			return err
+		}
+		if data.Opt == database.OptDelete {
+			err = tx.Table(data.Table).Where(fmt.Sprintf("%s = ?", pk), data.Key).Delete(nil).Error
+			if err != nil {
+				tx.Rollback()
+				return err
+			}
+		} else if data.Opt == database.OptAdd || data.Opt == database.OptUpdate {
+			isExist, err := s.Has(data.Table, data.Key)
+			if err != nil {
+				tx.Rollback()
+				return err
+			}
+			if isExist {
+				err = tx.Table(data.Table).Save(data.Value).Error
+			} else {
+				err = tx.Table(data.Table).Create(data.Value).Error
+			}
+			if err != nil {
+				tx.Rollback()
+				return err
+			}
+		}
+	}
+
+	if err := tx.Commit().Error; err != nil {
+		tx.Rollback()
+		return err
+	}
+	return nil
+}
+
+func initModelAndPrimaryKey(table string) (interface{}, string, error) {
+	m, ok := model.Models[table]
+	if !ok {
+		return nil, "", errors.New("unknown table: " + table)
+	}
+
+	ans := reflect.New(reflect.TypeOf(m).Elem()).Interface()
+	t := reflect.TypeOf(ans).Elem()
+	for i := 0; i < t.NumField(); i++ {
+		field := t.Field(i)
+		if tag := field.Tag.Get("gorm"); strings.Contains(tag, "primaryKey") {
+			column := getPrimaryKeyColumn(tag)
+			if column == "" {
+				return ans, field.Name, nil
+			}
+			return ans, column, nil
+		}
+	}
+	return ans, "", errors.New(table + " primary key not found")
+}
+
+func getPrimaryKeyColumn(s string) string {
+	splitStrings := strings.Split(s, ";")
+	for _, splitString := range splitStrings {
+		if strings.Contains(splitString, "column") {
+			columnParts := strings.Split(splitString, ":")
+			if len(columnParts) == 2 {
+				return columnParts[1]
+			}
+		}
+	}
+	return ""
+}
+
+func camelCaseToSnakeCase(s string) string {
+	r := regexp.MustCompile("([a-z0-9])([A-Z])")
+	snakeCase := r.ReplaceAllString(s, "${1}_${2}")
+	return strings.ToLower(snakeCase)
+}
diff --git a/config_server/v1/service/store/interface_database/interface_database.go b/config_server/v1/service/store/interface_database/interface_database.go
new file mode 100644
index 0000000000..ea6e2b7898
--- /dev/null
+++ b/config_server/v1/service/store/interface_database/interface_database.go
@@ -0,0 +1,80 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package database
+
+import (
+	"config-server/common"
+)
+
+/*
+Interface of store
+*/
+
+type Database interface {
+	Connect() error
+	GetMode() string // store mode
+	Close() error
+
+	Get(table string, entityKey string) (interface{}, error)
+	Add(table string, entityKey string, entity interface{}) error
+	Update(table string, entityKey string, entity interface{}) error
+	Has(table string, entityKey string) (bool, error)
+	Delete(table string, entityKey string) error
+	GetAll(table string) ([]interface{}, error)
+	Count(table string) (int, error)
+
+	WriteBatch(batch *Batch) error
+}
+
+// batch
+
+const (
+	OptAdd    string = "ADD"
+	OptDelete string = "DELETE"
+	OptUpdate string = "UPDATE"
+)
+
+type (
+	Data struct {
+		Opt   string
+		Table string
+		Key   string
+		Value interface{}
+	}
+
+	Batch struct {
+		datas common.Queue
+	}
+)
+
+func (b *Batch) Add(table string, entityKey string, entity interface{}) {
+	b.datas.Push(Data{OptAdd, table, entityKey, entity})
+}
+
+func (b *Batch) Update(table string, entityKey string, entity interface{}) {
+	b.datas.Push(Data{OptUpdate, table, entityKey, entity})
+}
+
+func (b *Batch) Delete(table string, entityKey string) {
+	b.datas.Push(Data{OptDelete, table, entityKey, nil})
+}
+
+func (b *Batch) Empty() bool {
+	return b.datas.Empty()
+}
+
+func (b *Batch) Pop() Data {
+	return b.datas.Pop().(Data)
+}
diff --git a/config_server/v1/service/store/leveldb/leveldb.go b/config_server/v1/service/store/leveldb/leveldb.go
new file mode 100644
index 0000000000..1c558222e2
--- /dev/null
+++ b/config_server/v1/service/store/leveldb/leveldb.go
@@ -0,0 +1,221 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package leveldb
+
+import (
+	"encoding/json"
+	"log"
+
+	"github.com/syndtr/goleveldb/leveldb"
+
+	"config-server/common"
+	"config-server/model"
+	"config-server/setting"
+	database "config-server/store/interface_database"
+)
+
+var dbPath = []string{
+	common.TypeAgentAttributes,
+	common.TypeAgent,
+	common.TypeConfigDetail,
+	common.TypeAgentGROUP,
+	common.TypeCommand,
+}
+
+type Store struct {
+	db map[string]*leveldb.DB
+}
+
+func (l *Store) Connect() error {
+	l.db = make(map[string]*leveldb.DB)
+
+	var err error
+	for _, c := range dbPath {
+		l.db[c], err = leveldb.OpenFile(setting.GetSetting().DbPath+"/"+c, nil)
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func (l *Store) GetMode() string {
+	return "leveldb"
+}
+
+func (l *Store) Close() error {
+	for _, db := range l.db {
+		err := db.Close()
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (l *Store) Get(table string, entityKey string) (interface{}, error) {
+	value, err := l.db[table].Get(generateKey(entityKey), nil)
+	if err != nil {
+		return nil, err
+	}
+	return parseValue(table, value), nil
+}
+
+func (l *Store) Add(table string, entityKey string, entity interface{}) error {
+	key := generateKey(entityKey)
+	value, err := generateValue(entity)
+	if err != nil {
+		return err
+	}
+
+	err = l.db[table].Put(key, value, nil)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (l *Store) Update(table string, entityKey string, entity interface{}) error {
+	key := generateKey(entityKey)
+	value, err := generateValue(entity)
+	if err != nil {
+		return err
+	}
+
+	err = l.db[table].Put(key, value, nil)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (l *Store) Has(table string, entityKey string) (bool, error) {
+	key := generateKey(entityKey)
+	ok, err := l.db[table].Has(key, nil)
+	if err != nil {
+		return false, err
+	}
+	return ok, nil
+}
+
+func (l *Store) Delete(table string, entityKey string) error {
+	key := generateKey(entityKey)
+	err := l.db[table].Delete(key, nil)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (l *Store) GetAll(table string) ([]interface{}, error) {
+	ans := make([]interface{}, 0)
+
+	iter := l.db[table].NewIterator(nil, nil)
+	for iter.Next() {
+		ans = append(ans, parseValue(table, iter.Value()))
+	}
+
+	iter.Release()
+	err := iter.Error()
+	if err != nil {
+		return nil, err
+	}
+	return ans, nil
+}
+
+func (l *Store) Count(table string) (int, error) {
+	var ans int
+
+	iter := l.db[table].NewIterator(nil, nil)
+	for iter.Next() {
+		ans++
+	}
+
+	iter.Release()
+	err := iter.Error()
+	if err != nil {
+		return 0, err
+	}
+	return ans, nil
+}
+
+func (l *Store) WriteBatch(batch *database.Batch) error {
+	batchTemp := *batch
+	var leveldbBatch map[string]*leveldb.Batch = make(map[string]*leveldb.Batch)
+
+	for !batch.Empty() {
+		data := batch.Pop()
+		key := generateKey(data.Key)
+
+		if _, ok := leveldbBatch[data.Table]; !ok {
+			leveldbBatch[data.Table] = new(leveldb.Batch)
+		}
+
+		if data.Opt == database.OptDelete {
+			leveldbBatch[data.Table].Delete(key)
+		} else if data.Opt == database.OptAdd || data.Opt == database.OptUpdate {
+			value, err := generateValue(data.Value)
+			if err != nil {
+				*batch = batchTemp
+				return err
+			}
+			leveldbBatch[data.Table].Put(key, value)
+		}
+	}
+
+	for t, b := range leveldbBatch {
+		err := l.db[t].Write(b, nil)
+		if err != nil {
+			*batch = batchTemp
+			return err
+		}
+	}
+
+	return nil
+}
+
+func generateKey(key string) []byte {
+	return []byte(key)
+}
+
+func generateValue(entity interface{}) ([]byte, error) {
+	value, err := json.Marshal(entity)
+	if err != nil {
+		return nil, err
+	}
+	return value, nil
+}
+
+func parseValue(table string, data []byte) interface{} {
+	var ans interface{}
+	switch table {
+	case common.TypeAgentAttributes:
+		ans = new(model.AgentAttributes)
+	case common.TypeAgent:
+		ans = new(model.Agent)
+	case common.TypeConfigDetail:
+		ans = new(model.ConfigDetail)
+	case common.TypeAgentGROUP:
+		ans = new(model.AgentGroup)
+	case common.TypeCommand:
+		ans = new(model.Command)
+	}
+	err := json.Unmarshal(data, ans)
+	if err != nil {
+		log.Println(err.Error())
+	}
+	return ans
+}
diff --git a/config_server/v1/service/store/store.go b/config_server/v1/service/store/store.go
new file mode 100644
index 0000000000..a94ceb082a
--- /dev/null
+++ b/config_server/v1/service/store/store.go
@@ -0,0 +1,63 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package store
+
+import (
+	"config-server/setting"
+	"config-server/store/gorm"
+	database "config-server/store/interface_database"
+	"config-server/store/leveldb"
+)
+
+// Data in database
+
+/*
+Store Factory
+*/
+func newStore(storeType string) database.Database {
+	switch storeType {
+	case "gorm":
+		return new(gorm.Store)
+	case "leveldb":
+		return new(leveldb.Store)
+	default:
+		panic("Wrong store type.")
+	}
+}
+
+var myStore database.Database
+
+/*
+Create a singleton of store
+*/
+func GetStore() database.Database {
+	return myStore
+}
+
+// batch
+
+func CreateBacth() *database.Batch {
+	return new(database.Batch)
+}
+
+// init
+
+func init() {
+	myStore = newStore(setting.GetSetting().StoreMode)
+	err := myStore.Connect()
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/config_server/v1/service/test/interface_test.go b/config_server/v1/service/test/interface_test.go
new file mode 100644
index 0000000000..388ec897e8
--- /dev/null
+++ b/config_server/v1/service/test/interface_test.go
@@ -0,0 +1,1231 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package test
+
+import (
+	"fmt"
+	"testing"
+	"time"
+
+	"github.com/gin-gonic/gin"
+	. "github.com/smartystreets/goconvey/convey"
+
+	"config-server/common"
+	proto "config-server/proto"
+	"config-server/router"
+)
+
+func TestBaseAgentGroup(t *testing.T) {
+	gin.SetMode(gin.TestMode)
+	r := gin.New()
+	router.InitUserRouter(r)
+
+	var requestID int
+
+	Convey("Test delete AgentGroup.", t, func() {
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete default. ")
+		{
+			status, res := DeleteAgentGroup(r, "default", fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.BadRequest.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
+			So(res.Message, ShouldEqual, "Cannot delete agent group 'default'")
+
+			requestID++
+		}
+	})
+}
+
+func TestBaseConfig(t *testing.T) {
+	gin.SetMode(gin.TestMode)
+	r := gin.New()
+	router.InitUserRouter(r)
+
+	var requestID int
+
+	Convey("Test create Config.", t, func() {
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-1. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-1"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test"
+			config.Context = "Description for test"
+
+			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-1. ")
+		{
+			configName := "config-1"
+
+			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get config success")
+			So(res.ConfigDetail.Name, ShouldEqual, configName)
+			So(res.ConfigDetail.Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
+			So(res.ConfigDetail.Detail, ShouldEqual, "Detail for test")
+			So(res.ConfigDetail.Context, ShouldEqual, "Description for test")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-1. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-1"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test"
+			config.Context = "Description for test"
+
+			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.ConfigAlreadyExist.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
+			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s already exists.", config.Name))
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get all configs. ")
+		{
+			status, res := ListConfigs(r, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get config list success")
+			So(len(res.ConfigDetails), ShouldEqual, 1)
+			So(res.ConfigDetails[0].Name, ShouldEqual, "config-1")
+			So(res.ConfigDetails[0].Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
+			So(res.ConfigDetails[0].Detail, ShouldEqual, "Detail for test")
+			So(res.ConfigDetails[0].Context, ShouldEqual, "Description for test")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-2. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-2"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Context = "Description for test"
+
+			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.BadRequest.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
+			So(res.Message, ShouldEqual, fmt.Sprintf("Need parameter %s.", "Detail"))
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-2. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-2"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test"
+			config.Context = "Description for test"
+
+			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-2. ")
+		{
+			configName := "config-2"
+
+			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get config success")
+			So(res.ConfigDetail.Name, ShouldEqual, configName)
+			So(res.ConfigDetail.Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
+			So(res.ConfigDetail.Detail, ShouldEqual, "Detail for test")
+			So(res.ConfigDetail.Context, ShouldEqual, "Description for test")
+
+			requestID++
+		}
+	})
+
+	Convey("Test update Config.", t, func() {
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test update config-1. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-1"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test-updated"
+			config.Context = "Description for test-updated"
+
+			status, res := UpdateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Update config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-1. ")
+		{
+			configName := "config-1"
+
+			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get config success")
+			So(res.ConfigDetail.Name, ShouldEqual, configName)
+			So(res.ConfigDetail.Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
+			So(res.ConfigDetail.Detail, ShouldEqual, "Detail for test-updated")
+			So(res.ConfigDetail.Context, ShouldEqual, "Description for test-updated")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test update config-2. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-2"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test-updated"
+			config.Context = "Description for test-updated"
+
+			status, res := UpdateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Update config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-2. ")
+		{
+			configName := "config-2"
+
+			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get config success")
+			So(res.ConfigDetail.Name, ShouldEqual, configName)
+			So(res.ConfigDetail.Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
+			So(res.ConfigDetail.Detail, ShouldEqual, "Detail for test-updated")
+			So(res.ConfigDetail.Context, ShouldEqual, "Description for test-updated")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test update config-3. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-3"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test-updated"
+			config.Context = "Description for test-updated"
+
+			status, res := UpdateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.ConfigNotExist.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
+			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s doesn't exist.", config.Name))
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get all configs. ")
+		{
+			status, res := ListConfigs(r, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get config list success")
+			So(len(res.ConfigDetails), ShouldEqual, 2)
+			So(res.ConfigDetails[0].Name, ShouldEqual, "config-1")
+			So(res.ConfigDetails[0].Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
+			So(res.ConfigDetails[0].Detail, ShouldEqual, "Detail for test-updated")
+			So(res.ConfigDetails[0].Context, ShouldEqual, "Description for test-updated")
+			So(res.ConfigDetails[1].Name, ShouldEqual, "config-2")
+			So(res.ConfigDetails[1].Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
+			So(res.ConfigDetails[1].Detail, ShouldEqual, "Detail for test-updated")
+			So(res.ConfigDetails[1].Context, ShouldEqual, "Description for test-updated")
+
+			requestID++
+		}
+	})
+
+	Convey("Test delete Config.", t, func() {
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-1. ")
+		{
+			configName := "config-1"
+
+			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Delete config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-1. ")
+		{
+			configName := "config-1"
+
+			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.ConfigNotExist.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
+			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s doesn't exist.", configName))
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-1. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-1"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test"
+			config.Context = "Description for test"
+
+			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-1. ")
+		{
+			configName := "config-1"
+
+			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get config success")
+			So(res.ConfigDetail.Name, ShouldEqual, configName)
+			So(res.ConfigDetail.Type, ShouldEqual, proto.ConfigType_PIPELINE_CONFIG)
+			So(res.ConfigDetail.Detail, ShouldEqual, "Detail for test")
+			So(res.ConfigDetail.Context, ShouldEqual, "Description for test")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-1. ")
+		{
+			configName := "config-1"
+
+			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Delete config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-1. ")
+		{
+			configName := "config-1"
+
+			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.ConfigNotExist.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
+			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s doesn't exist.", configName))
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-2. ")
+		{
+			configName := "config-2"
+
+			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Delete config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-2. ")
+		{
+			configName := "config-2"
+
+			status, res := GetConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.ConfigNotExist.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
+			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s doesn't exist.", configName))
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get all configs. ")
+		{
+			status, res := ListConfigs(r, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get config list success")
+			So(len(res.ConfigDetails), ShouldEqual, 0)
+
+			requestID++
+		}
+	})
+}
+
+func TestOperationsBetweenConfigAndAgentGroup(t *testing.T) {
+	gin.SetMode(gin.TestMode)
+	r := gin.New()
+	router.InitUserRouter(r)
+
+	var requestID int
+
+	Convey("Test apply.", t, func() {
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-1. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-1"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test"
+			config.Context = "Description for test"
+
+			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-2. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-2"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test"
+			config.Context = "Description for test"
+
+			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test apply config-1 to default. ")
+		{
+			configName := "config-1"
+			groupName := "default"
+
+			status, res := ApplyConfigToAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config to agent group success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get default's Configs. ")
+		{
+			groupName := "default"
+
+			status, res := GetAppliedConfigsForAgentGroup(r, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get agent group's applied configs success")
+			So(len(res.ConfigNames), ShouldEqual, 1)
+			So(res.ConfigNames[0], ShouldEqual, "config-1")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-1's AgentGroups. ")
+		{
+			configName := "config-1"
+
+			status, res := GetAppliedAgentGroups(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get group list success")
+			So(len(res.AgentGroupNames), ShouldEqual, 1)
+			So(res.AgentGroupNames[0], ShouldEqual, "default")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get config-3's AgentGroups. ")
+		{
+			configName := "config-3"
+
+			status, res := GetAppliedAgentGroups(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.ConfigNotExist.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_INVALID_PARAMETER)
+			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s doesn't exist.", configName))
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test apply config-2 to default. ")
+		{
+			configName := "config-2"
+			groupName := "default"
+
+			status, res := ApplyConfigToAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config to agent group success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get default's Configs. ")
+		{
+			groupName := "default"
+
+			status, res := GetAppliedConfigsForAgentGroup(r, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get agent group's applied configs success")
+			So(len(res.ConfigNames), ShouldEqual, 2)
+			So(res.ConfigNames, ShouldContain, "config-1")
+			So(res.ConfigNames, ShouldContain, "config-2")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-1. ")
+		{
+			configName := "config-1"
+
+			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.InternalServerError.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_INTERNAL_SERVER_ERROR)
+			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s was applied to some agent groups, cannot be deleted.", configName))
+
+			requestID++
+		}
+	})
+
+	Convey("Test remove.", t, func() {
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-2. ")
+		{
+			configName := "config-2"
+
+			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.InternalServerError.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_INTERNAL_SERVER_ERROR)
+			So(res.Message, ShouldEqual, fmt.Sprintf("Config %s was applied to some agent groups, cannot be deleted.", configName))
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test remove config-2 from default. ")
+		{
+			configName := "config-2"
+			groupName := "default"
+
+			status, res := RemoveConfigFromAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Remove config from agent group success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get default's Configs. ")
+		{
+			groupName := "default"
+
+			status, res := GetAppliedConfigsForAgentGroup(r, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get agent group's applied configs success")
+			So(len(res.ConfigNames), ShouldEqual, 1)
+			So(res.ConfigNames[0], ShouldEqual, "config-1")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-2. ")
+		{
+			configName := "config-2"
+
+			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Delete config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test remove config-1 from default. ")
+		{
+			configName := "config-1"
+			groupName := "default"
+
+			status, res := RemoveConfigFromAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Remove config from agent group success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get default's Configs. ")
+		{
+			groupName := "default"
+
+			status, res := GetAppliedConfigsForAgentGroup(r, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get agent group's applied configs success")
+			So(len(res.ConfigNames), ShouldEqual, 0)
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-1. ")
+		{
+			configName := "config-1"
+
+			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Delete config success")
+
+			requestID++
+		}
+	})
+}
+
+func TestAgentSendMessage(t *testing.T) {
+	gin.SetMode(gin.TestMode)
+	r := gin.New()
+	router.InitAgentRouter(r)
+	router.InitUserRouter(r)
+
+	var requestID int
+
+	Convey("Test Agent send message.", t, func() {
+		configInfos := make([]*proto.ConfigCheckResult, 0)
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test ilogtail-1 send Heartbeat. ")
+		{
+			agent := new(proto.Agent)
+			agent.AgentId = "ilogtail-1"
+			agent.Attributes = &proto.AgentAttributes{}
+			agent.RunningStatus = "good"
+			agent.StartupTime = 100
+
+			status, res := HeartBeat(r, agent, configInfos, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Send heartbeat successGet config update infos success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Sleep 1s. ")
+		{
+			time.Sleep(time.Second * 1)
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test ilogtail-2 send Heartbeat. ")
+		{
+			agent := new(proto.Agent)
+			agent.AgentId = "ilogtail-2"
+			agent.Attributes = &proto.AgentAttributes{}
+			agent.RunningStatus = "good"
+			agent.StartupTime = 200
+
+			status, res := HeartBeat(r, agent, configInfos, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Send heartbeat successGet config update infos success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Sleep 1s. ")
+		{
+			time.Sleep(time.Second * 1)
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test ilogtail-1 send Heartbeat. ")
+		{
+			agent := new(proto.Agent)
+			agent.AgentId = "ilogtail-1"
+			agent.Attributes = &proto.AgentAttributes{}
+			agent.RunningStatus = "good"
+			agent.StartupTime = 100
+
+			status, res := HeartBeat(r, agent, configInfos, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Send heartbeat successGet config update infos success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Sleep 2s, wait for writing agent info to store. ")
+		{
+			time.Sleep(time.Second * 2)
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test get default's Agents. ")
+		{
+			groupName := "default"
+
+			status, res := ListAgents(r, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get agent list success")
+			So(len(res.Agents), ShouldEqual, 2)
+			requestID++
+		}
+	})
+}
+
+func TestAgentGetConfig(t *testing.T) {
+	gin.SetMode(gin.TestMode)
+	r := gin.New()
+	router.InitAgentRouter(r)
+	router.InitUserRouter(r)
+
+	var requestID int
+
+	Convey("Test Agent get config.", t, func() {
+		agent := new(proto.Agent)
+		agent.AgentId = "ilogtail-1"
+		agent.Attributes = &proto.AgentAttributes{}
+		agent.RunningStatus = "good"
+		agent.StartupTime = 100
+
+		configVersions := map[string]int64{}
+		configInfos := make([]*proto.ConfigCheckResult, 0)
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-1. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-1"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test"
+			config.Context = "Description for test"
+
+			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-2. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-2"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test"
+			config.Context = "Description for test"
+
+			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-3. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-3"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test"
+			config.Context = "Description for test"
+
+			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test create config-4. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-4"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test"
+			config.Context = "Description for test"
+
+			status, res := CreateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test apply config-1 to default. ")
+		{
+			configName := "config-1"
+			groupName := "default"
+
+			status, res := ApplyConfigToAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config to agent group success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test apply config-2 to default. ")
+		{
+			configName := "config-2"
+			groupName := "default"
+
+			status, res := ApplyConfigToAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config to agent group success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test apply config-3 to default. ")
+		{
+			configName := "config-3"
+			groupName := "default"
+
+			status, res := ApplyConfigToAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config to agent group success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Sleep 3s, wait for writing config info to store. ")
+		{
+			time.Sleep(time.Second * 3)
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test ilogtail-1 send Heartbeat. ")
+		{
+			status, res := HeartBeat(r, agent, configInfos, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Send heartbeat successGet config update infos success")
+			So(len(res.PipelineCheckResults), ShouldEqual, 3)
+			for _, info := range res.PipelineCheckResults {
+				configVersions[info.Name] = info.NewVersion
+				switch info.Name {
+				case "config-1":
+					So(info.CheckStatus, ShouldEqual, proto.CheckStatus_NEW)
+				case "config-2":
+					So(info.CheckStatus, ShouldEqual, proto.CheckStatus_NEW)
+				case "config-3":
+					So(info.CheckStatus, ShouldEqual, proto.CheckStatus_NEW)
+				}
+			}
+			configInfos = res.PipelineCheckResults
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test fetch ilogtail-1's configs. ")
+		{
+			status, res := FetchPipelineConfig(r, configInfos, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get Agent Config details success")
+			So(len(res.ConfigDetails), ShouldEqual, 3)
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test apply config-4 to default. ")
+		{
+			configName := "config-4"
+			groupName := "default"
+
+			status, res := ApplyConfigToAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Add config to agent group success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test remove config-1 from default. ")
+		{
+			configName := "config-1"
+			groupName := "default"
+
+			status, res := RemoveConfigFromAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Remove config from agent group success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test update config-2. ")
+		{
+			config := &proto.ConfigDetail{}
+			config.Name = "config-2"
+			config.Type = proto.ConfigType_PIPELINE_CONFIG
+			config.Detail = "Detail for test-updated"
+			config.Context = "Description for test-updated"
+
+			status, res := UpdateConfig(r, config, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Update config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Sleep 3s, wait for writing config info to store. ")
+		{
+			time.Sleep(time.Second * 3)
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test ilogtail-1 send Heartbeat. ")
+		{
+			status, res := HeartBeat(r, agent, configInfos, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Send heartbeat successGet config update infos success")
+			So(len(res.PipelineCheckResults), ShouldEqual, 3)
+			configVersions = map[string]int64{}
+			for _, info := range res.PipelineCheckResults {
+				configVersions[info.Name] = info.NewVersion
+				switch info.Name {
+				case "config-1":
+					So(info.CheckStatus, ShouldEqual, proto.CheckStatus_DELETED)
+				case "config-2":
+					So(info.CheckStatus, ShouldEqual, proto.CheckStatus_MODIFIED)
+				case "config-4":
+					So(info.CheckStatus, ShouldEqual, proto.CheckStatus_NEW)
+				}
+			}
+			configInfos = res.PipelineCheckResults
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test fetch ilogtail-1's configs. ")
+		{
+			status, res := FetchPipelineConfig(r, configInfos, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.RequestId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Get Agent Config details success")
+			So(len(res.ConfigDetails), ShouldEqual, 3)
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test remove config-2 from default. ")
+		{
+			configName := "config-2"
+			groupName := "default"
+
+			status, res := RemoveConfigFromAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Remove config from agent group success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test remove config-3 from default. ")
+		{
+			configName := "config-3"
+			groupName := "default"
+
+			status, res := RemoveConfigFromAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Remove config from agent group success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test remove config-4 from default. ")
+		{
+			configName := "config-4"
+			groupName := "default"
+
+			status, res := RemoveConfigFromAgentGroup(r, configName, groupName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Remove config from agent group success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-1. ")
+		{
+			configName := "config-1"
+
+			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Delete config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-2. ")
+		{
+			configName := "config-2"
+
+			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Delete config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-3. ")
+		{
+			configName := "config-3"
+
+			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Delete config success")
+
+			requestID++
+		}
+
+		fmt.Print("\n\t" + fmt.Sprint(requestID) + ":Test delete config-4. ")
+		{
+			configName := "config-4"
+
+			status, res := DeleteConfig(r, configName, fmt.Sprint(requestID))
+
+			// check
+			So(status, ShouldEqual, common.Accept.Status)
+			So(res.ResponseId, ShouldEqual, fmt.Sprint(requestID))
+			So(res.Code, ShouldEqual, proto.RespCode_ACCEPT)
+			So(res.Message, ShouldEqual, "Delete config success")
+
+			requestID++
+		}
+	})
+}
diff --git a/config_server/v1/service/test/request.go b/config_server/v1/service/test/request.go
new file mode 100644
index 0000000000..9f2e85d74e
--- /dev/null
+++ b/config_server/v1/service/test/request.go
@@ -0,0 +1,323 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package test
+
+import (
+	"bytes"
+	"io"
+	"net/http"
+	"net/http/httptest"
+
+	"github.com/gin-gonic/gin"
+	"google.golang.org/protobuf/proto"
+
+	configserverproto "config-server/proto"
+)
+
+func DeleteAgentGroup(r *gin.Engine, groupName string, requestID string) (int, *configserverproto.DeleteAgentGroupResponse) {
+	// data
+	reqBody := configserverproto.DeleteAgentGroupRequest{}
+	reqBody.RequestId = requestID
+	reqBody.GroupName = groupName
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("DELETE", "/User/DeleteAgentGroup", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.DeleteAgentGroupResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
+
+func CreateConfig(r *gin.Engine, config *configserverproto.ConfigDetail, requestID string) (int, *configserverproto.CreateConfigResponse) {
+	// data
+	reqBody := configserverproto.CreateConfigRequest{}
+	reqBody.RequestId = requestID
+	reqBody.ConfigDetail = config
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("POST", "/User/CreateConfig", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.CreateConfigResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
+
+func GetConfig(r *gin.Engine, configName string, requestID string) (int, *configserverproto.GetConfigResponse) {
+	// data
+	reqBody := configserverproto.GetConfigRequest{}
+	reqBody.RequestId = requestID
+	reqBody.ConfigName = configName
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("POST", "/User/GetConfig", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.GetConfigResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
+
+func UpdateConfig(r *gin.Engine, config *configserverproto.ConfigDetail, requestID string) (int, *configserverproto.UpdateConfigResponse) {
+	// data
+	reqBody := configserverproto.UpdateConfigRequest{}
+	reqBody.RequestId = requestID
+	reqBody.ConfigDetail = config
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("PUT", "/User/UpdateConfig", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.UpdateConfigResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
+
+func DeleteConfig(r *gin.Engine, configName string, requestID string) (int, *configserverproto.DeleteConfigResponse) {
+	// data
+	reqBody := configserverproto.DeleteConfigRequest{}
+	reqBody.RequestId = requestID
+	reqBody.ConfigName = configName
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("DELETE", "/User/DeleteConfig", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.DeleteConfigResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
+
+func ListConfigs(r *gin.Engine, requestID string) (int, *configserverproto.ListConfigsResponse) {
+	// data
+	reqBody := configserverproto.ListConfigsRequest{}
+	reqBody.RequestId = requestID
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("POST", "/User/ListConfigs", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.ListConfigsResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
+
+func ApplyConfigToAgentGroup(r *gin.Engine, configName string, groupName string, requestID string) (int, *configserverproto.ApplyConfigToAgentGroupResponse) {
+	// data
+	reqBody := configserverproto.ApplyConfigToAgentGroupRequest{}
+	reqBody.RequestId = requestID
+	reqBody.ConfigName = configName
+	reqBody.GroupName = groupName
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("PUT", "/User/ApplyConfigToAgentGroup", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.ApplyConfigToAgentGroupResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
+
+func RemoveConfigFromAgentGroup(r *gin.Engine, configName string, groupName string, requestID string) (int, *configserverproto.RemoveConfigFromAgentGroupResponse) {
+	// data
+	reqBody := configserverproto.RemoveConfigFromAgentGroupRequest{}
+	reqBody.RequestId = requestID
+	reqBody.ConfigName = configName
+	reqBody.GroupName = groupName
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("DELETE", "/User/RemoveConfigFromAgentGroup", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.RemoveConfigFromAgentGroupResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
+
+func GetAppliedConfigsForAgentGroup(r *gin.Engine, groupName string, requestID string) (int, *configserverproto.GetAppliedConfigsForAgentGroupResponse) {
+	// data
+	reqBody := configserverproto.GetAppliedConfigsForAgentGroupRequest{}
+	reqBody.RequestId = requestID
+	reqBody.GroupName = groupName
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("POST", "/User/GetAppliedConfigsForAgentGroup", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.GetAppliedConfigsForAgentGroupResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
+
+func GetAppliedAgentGroups(r *gin.Engine, configName string, requestID string) (int, *configserverproto.GetAppliedAgentGroupsResponse) {
+	// data
+	reqBody := configserverproto.GetAppliedAgentGroupsRequest{}
+	reqBody.RequestId = requestID
+	reqBody.ConfigName = configName
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("POST", "/User/GetAppliedAgentGroups", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.GetAppliedAgentGroupsResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
+
+func ListAgents(r *gin.Engine, groupName string, requestID string) (int, *configserverproto.ListAgentsResponse) {
+	// data
+	reqBody := configserverproto.ListAgentsRequest{}
+	reqBody.RequestId = requestID
+	reqBody.GroupName = groupName
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("POST", "/User/ListAgents", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.ListAgentsResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
+
+func HeartBeat(r *gin.Engine, agent *configserverproto.Agent, configInfos []*configserverproto.ConfigCheckResult, requestID string) (int, *configserverproto.HeartBeatResponse) {
+	// data
+	reqBody := configserverproto.HeartBeatRequest{}
+	reqBody.RequestId = requestID
+	reqBody.AgentId = agent.AgentId
+	reqBody.AgentType = agent.AgentType
+	reqBody.Attributes = agent.Attributes
+	reqBody.RunningStatus = agent.RunningStatus
+	reqBody.StartupTime = agent.StartupTime
+	reqBody.Tags = agent.Tags
+	pipelineConfigs := make([]*configserverproto.ConfigInfo, 0)
+	for _, c := range configInfos {
+		conf := new(configserverproto.ConfigInfo)
+		conf.Type = c.Type
+		conf.Name = c.Name
+		conf.Version = c.OldVersion
+		pipelineConfigs = append(pipelineConfigs, conf)
+	}
+	reqBody.PipelineConfigs = pipelineConfigs
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("POST", "/Agent/HeartBeat", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.HeartBeatResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
+
+func FetchPipelineConfig(r *gin.Engine, configInfos []*configserverproto.ConfigCheckResult, requestID string) (int, *configserverproto.FetchPipelineConfigResponse) {
+	// data
+	reqBody := configserverproto.FetchPipelineConfigRequest{}
+	reqBody.RequestId = requestID
+	reqBody.ReqConfigs = make([]*configserverproto.ConfigInfo, 0)
+	for _, c := range configInfos {
+		conf := new(configserverproto.ConfigInfo)
+		conf.Name = c.Name
+		conf.Context = c.Context
+		conf.Type = c.Type
+		conf.Version = c.NewVersion
+		reqBody.ReqConfigs = append(reqBody.ReqConfigs, conf)
+	}
+	reqBodyByte, _ := proto.Marshal(&reqBody)
+
+	// request
+	w := httptest.NewRecorder()
+	req, _ := http.NewRequest("POST", "/Agent/FetchPipelineConfig", bytes.NewBuffer(reqBodyByte))
+	r.ServeHTTP(w, req)
+
+	// response
+	res := w.Result()
+	resBodyByte, _ := io.ReadAll(res.Body)
+	resBody := new(configserverproto.FetchPipelineConfigResponse)
+	_ = proto.Unmarshal(resBodyByte, resBody)
+
+	return res.StatusCode, resBody
+}
diff --git a/config_server/v1/service/test/setting/setting.json b/config_server/v1/service/test/setting/setting.json
new file mode 100644
index 0000000000..e34bbfa186
--- /dev/null
+++ b/config_server/v1/service/test/setting/setting.json
@@ -0,0 +1 @@
+{"ip":"127.0.0.1","store_mode":"leveldb","port":"8899","db_path":"./DB","agent_update_interval":1,"config_sync_interval":3}
\ No newline at end of file
diff --git a/config_server/v1/service/test/setting_test.go b/config_server/v1/service/test/setting_test.go
new file mode 100644
index 0000000000..12b997cb7a
--- /dev/null
+++ b/config_server/v1/service/test/setting_test.go
@@ -0,0 +1,37 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package test
+
+import (
+	"testing"
+
+	. "github.com/smartystreets/goconvey/convey"
+
+	"config-server/setting"
+)
+
+func TestSetting(t *testing.T) {
+	Convey("Test load setting.", t, func() {
+		So(setting.GetSetting().StoreMode, ShouldEqual, "leveldb")
+	})
+
+	Convey("Test update setting.", t, func() {
+		So(setting.GetSetting().StoreMode, ShouldEqual, "leveldb")
+		setting.UpdateSetting(map[string]interface{}{"store_mode": "mysql"})
+		So(setting.GetSetting().StoreMode, ShouldEqual, "mysql")
+		setting.UpdateSetting(map[string]interface{}{"store_mode": "leveldb"})
+		So(setting.GetSetting().StoreMode, ShouldEqual, "leveldb")
+	})
+}
diff --git a/config_server/v1/service/test/store_test.go b/config_server/v1/service/test/store_test.go
new file mode 100644
index 0000000000..c63074e448
--- /dev/null
+++ b/config_server/v1/service/test/store_test.go
@@ -0,0 +1,68 @@
+// Copyright 2022 iLogtail Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package test
+
+import (
+	"testing"
+
+	. "github.com/smartystreets/goconvey/convey"
+
+	"config-server/common"
+	"config-server/model"
+	"config-server/store"
+)
+
+func TestStore(t *testing.T) {
+	Convey("Test load store, check it's type.", t, func() {
+		So(store.GetStore().GetMode(), ShouldEqual, "leveldb")
+	})
+
+	Convey("Test store's CURD, take config as example.", t, func() {
+		s := store.GetStore()
+
+		Convey("First, add a config named config-test to store.", func() {
+			config := new(model.ConfigDetail)
+			config.Name = "config-test"
+			config.Type = "PIPELINE_CONFIG"
+			config.Detail = "test"
+			config.Version = 1
+			config.Context = ""
+			config.DelTag = false
+			s.Add(common.TypeConfigDetail, config.Name, config)
+
+			value, getErr := s.Get(common.TypeConfigDetail, "config-test")
+			So(getErr, ShouldBeNil)
+			So(value.(*model.ConfigDetail), ShouldResemble, &model.ConfigDetail{Name: "config-test", Type: "PIPELINE_CONFIG", Detail: "test", Version: 1, Context: "", DelTag: false})
+		})
+
+		Convey("Second, update config-test's content.", func() {
+			value, getErr := s.Get(common.TypeConfigDetail, "config-test")
+			So(getErr, ShouldBeNil)
+			config := value.(*model.ConfigDetail)
+			config.Context = "test"
+			s.Update(common.TypeConfigDetail, config.Name, config)
+
+			value, getErr = s.Get(common.TypeConfigDetail, "config-test")
+			So(getErr, ShouldBeNil)
+			So(value.(*model.ConfigDetail), ShouldResemble, &model.ConfigDetail{Name: "config-test", Type: "PIPELINE_CONFIG", Detail: "test", Version: 1, Context: "test", DelTag: false})
+		})
+
+		Convey("Third, delete config-test.", func() {
+			s.Delete(common.TypeConfigDetail, "config-test")
+			_, getErr := s.Get(common.TypeConfigDetail, "config-test")
+			So(getErr, ShouldNotBeNil)
+		})
+	})
+}
diff --git a/config_server/ui/README.md b/config_server/v1/ui/README.md
similarity index 100%
rename from config_server/ui/README.md
rename to config_server/v1/ui/README.md
diff --git a/config_server/v2/README.md b/config_server/v2/README.md
new file mode 100644
index 0000000000..76e2b4557c
--- /dev/null
+++ b/config_server/v2/README.md
@@ -0,0 +1,12 @@
+# Config-server
+
+这是基于阿里巴巴 iLogtail 项目 Config Server v2通信协议的一个前后端实现。
+
+后端使用GO基于gin框架开发,针对https://github.com/alibaba/ilogtail/tree/main/config_server/protocol/v2 中提到的Agent行为进行了V2版本的适配,基本实现了能力报告、心跳压缩、配置状态上报等功能,并包含用户端接口,详情见[service](service/README.md)。
+
+前端使用 Vue + Element plus 组件库 + Vue cli 脚手架工具进行开发,旨在为用户提供一个简单、实用、易嵌入的 Config Server 前端控制台,详情见[ui](ui/README.md)。
+
+本项目提供了docker compose一键部署脚本,帮助用户快速搭建可用可视化与agent连通的config-server应用,详情见[deployment](deployment/README.md)。
+
+
+
diff --git a/config_server/v2/protocol/README.md b/config_server/v2/protocol/README.md
new file mode 100644
index 0000000000..783fb68970
--- /dev/null
+++ b/config_server/v2/protocol/README.md
@@ -0,0 +1,7 @@
+# 管控协议说明
+
+ConfigServer管控协议的总贴、V1版本协议说明和翻新至V2的讨论参见
+[服务端管控协议共建,欢迎参与讨论交流](https://github.com/alibaba/ilogtail/discussions/404)。
+
+V2版本的讨论参见
+[心跳&配置同步流程重构讨论](https://github.com/alibaba/ilogtail/discussions/1491#discussioncomment-9547735)。
diff --git a/config_server/v2/protocol/v1/agent.proto b/config_server/v2/protocol/v1/agent.proto
new file mode 100644
index 0000000000..fe56d24f0d
--- /dev/null
+++ b/config_server/v2/protocol/v1/agent.proto
@@ -0,0 +1,134 @@
+syntax = "proto3";
+package configserver.proto;
+option go_package = ".;configserver_proto";
+
+// Define Config's type
+enum ConfigType {
+    PIPELINE_CONFIG = 0; 
+    AGENT_CONFIG = 1;      
+}
+
+// Define Config's update status
+enum CheckStatus {
+    NEW = 0;
+    DELETED = 1;
+    MODIFIED = 2;
+}
+
+// Define response code
+enum RespCode {
+    ACCEPT = 0;                 
+    INVALID_PARAMETER = 1;      
+    INTERNAL_SERVER_ERROR = 2;  
+}
+
+// Define the Config information carried in the request
+message ConfigInfo {
+    ConfigType type = 1;    // Required, Config's type
+    string name = 2;        // Required, Config's unique identification
+    int64 version = 3;      // Required, Config's version number
+    string context = 4;     // Config's context
+}
+
+// Define the result of checking the Config update status
+message ConfigCheckResult {
+    ConfigType type = 1;            // Required, Config's type
+    string name = 2;                // Required, Config's unique identification
+    int64 old_version = 3;          // Required, Config's current version number
+    int64 new_version = 4;          // Required, Config's latest version number
+    string context = 5;             // Config's context
+    CheckStatus check_status = 6;   // Required, Config's update status   
+}
+
+// Define Config's detail
+message ConfigDetail {
+    ConfigType type = 1;    // Required, Config's type
+    string name = 2;        // Required, Config's unique identification
+    int64 version = 3;      // Required, Config's version number
+    string context = 4;     // Config's context
+    string detail = 5;      // Required, Config's detail
+}
+
+// Define Agent's basic attributes
+message AgentAttributes {
+    string version = 1;                 // Agent's version
+    string category = 2;                // Agent's type(used to distinguish AGENT_CONFIG)
+    string ip = 3;                      // Agent's ip
+    string hostname = 4;                // Agent's hostname
+    string region = 5;                  // Agent's region
+    string zone = 6;                    // Agent's zone
+    map<string, string> extras = 100;   // Agent's other attributes
+}
+
+// Define command
+message Command {
+    string type = 1;                // Required, Command type
+    string name = 2;                // Required, Command name
+    string id = 3;                  // Required, Command id
+    map<string, string> args = 4;   // Command's parameter arrays
+}
+
+// API: /Agent/HeartBeat/
+
+// Agent sends requests to the ConfigServer to send heartbeats, get config updates and receive commands.
+message HeartBeatRequest {
+    string request_id = 1;  
+
+    string agent_id = 2;                        // Required, Agent's unique identification
+    string agent_type = 3;                      // Required, Agent's type(ilogtail, ..)
+    AgentAttributes attributes = 4;             // Agent's basic attributes
+    repeated string tags =  5;                  // Agent's tags
+    string running_status = 6;                  // Required, Agent's running status
+    int64 startup_time = 7;                     // Required, Agent's startup time
+    int32 interval = 8;                         // Agent's heartbeat interval
+    repeated ConfigInfo pipeline_configs = 9;   // Information about the current PIPELINE_CONFIG held by the Agent
+    repeated ConfigInfo agent_configs = 10;     // Information about the current AGENT_CONFIG held by the Agent
+}
+
+// ConfigServer's response to Agent's heartbeats
+message HeartBeatResponse {
+    string request_id = 1;  
+    RespCode code = 2;      
+    string message = 3;     
+
+    repeated ConfigCheckResult pipeline_check_results = 4;  // Agent's PIPELINE_CONFIG update status
+    repeated ConfigCheckResult agent_check_results = 5;     // Agent's AGENT_CONFIG update status
+    repeated Command custom_commands = 6;                   // Agent received commands
+}
+
+// API: /Agent/FetchPipelineConfig/
+// Agent request to ConfigServer, pulling details of the PIPELINE_CONFIG
+message FetchPipelineConfigRequest {
+    string request_id = 1; 
+
+    string agent_id = 2;                    // Required, Agent's unique identification
+    repeated ConfigInfo req_configs = 3;    // PIPELINE_CONFIGs that Agent requires for full information
+}
+
+// ConfigServer response to Agent's request
+message FetchPipelineConfigResponse {
+    string request_id = 1;                     
+    RespCode code = 2;      
+    string message = 3;     
+
+    repeated ConfigDetail config_details = 4;   // PIPELINE_CONFIGs' detail
+}
+
+// API: /Agent/FetchAgentConfig/
+// Agent request to ConfigServer, pulling details of the AGENT_CONFIG
+message FetchAgentConfigRequest {
+    string request_id = 1; 
+
+    string agent_id = 2;                    // Required, Agent's unique identification
+    AgentAttributes attributes = 3;         // Required, Agent's basic attributes
+    repeated ConfigInfo req_configs = 4;    // AGENT_CONFIGs that Agent requires for full information
+}
+
+// ConfigServer response to Agent's request
+message FetchAgentConfigResponse {
+    string request_id = 1;         
+    RespCode code = 2;               
+    string message = 3;                   
+
+    repeated ConfigDetail config_details = 4;   // AGENT_CONFIGs' detail
+}
\ No newline at end of file
diff --git a/config_server/v2/protocol/v1/user.proto b/config_server/v2/protocol/v1/user.proto
new file mode 100644
index 0000000000..4a6147fdc2
--- /dev/null
+++ b/config_server/v2/protocol/v1/user.proto
@@ -0,0 +1,234 @@
+syntax = "proto3";
+package configserver.proto;
+option go_package = ".;configserver_proto";
+import "agent.proto";
+
+message AgentGroupTag {
+    string name = 1;
+    string value = 2;
+}
+
+message AgentGroup {
+    string group_name = 1;
+    string description = 2;
+    repeated AgentGroupTag tags = 3;
+}
+
+message Agent {
+    string agent_id = 1;            // Required, Agent's unique identification
+    string agent_type = 2;          // Required, Agent's type(ilogtail, ..)
+    AgentAttributes attributes = 3; // Agent's basic attributes
+    repeated string tags =  4;      // Agent's tags
+    string running_status = 5;      // Required, Agent's running status
+    int64 startup_time = 6;         // Required, Agent's startup time
+    int32 interval = 7;             // Agent's heartbeat interval
+}
+
+// API: /User/CreateAgentGroup
+
+message CreateAgentGroupRequest {
+    string request_id = 1;
+    AgentGroup agent_group = 2;
+}
+
+message CreateAgentGroupResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+}
+
+// API: /User/UpdateAgentGroup
+
+message UpdateAgentGroupRequest {
+    string request_id = 1;
+    AgentGroup agent_group = 2;
+}
+
+message UpdateAgentGroupResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+}
+
+// API: /User/DeleteAgentGroup/
+
+message DeleteAgentGroupRequest {
+    string request_id = 1;
+    string group_name = 2;
+}
+
+message DeleteAgentGroupResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+}
+
+// API: /User/GetAgentGroup/
+
+message GetAgentGroupRequest {
+    string request_id = 1;
+    string group_name = 2;
+}
+
+message GetAgentGroupResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+
+    AgentGroup agent_group = 4;
+}
+
+// API: /User/ListAgentGroups/ 
+
+message ListAgentGroupsRequest {
+    string request_id = 1;
+}
+
+message ListAgentGroupsResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+
+    repeated AgentGroup agent_groups = 4;
+}
+
+// API: /User/CreateConfig/
+
+message CreateConfigRequest {
+    string request_id = 1;
+    ConfigDetail config_detail = 2;
+}
+
+message CreateConfigResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+}
+
+// API: /User/UpdateConfig/
+
+message UpdateConfigRequest {
+    string request_id = 1;
+    ConfigDetail config_detail = 2;
+}
+
+message UpdateConfigResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+}
+
+// API: /User/DeleteConfig/
+
+message DeleteConfigRequest {
+    string request_id = 1;
+    string config_name = 2;
+}
+
+message DeleteConfigResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+}
+
+// API: User/GetConfig/
+
+message GetConfigRequest {
+    string request_id = 1;
+    string config_name = 2;
+}
+
+message GetConfigResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+
+    ConfigDetail config_detail = 4;
+}
+
+// API: /User/ListConfigs/
+
+message ListConfigsRequest {
+    string request_id = 1;
+}
+
+message ListConfigsResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+
+    repeated ConfigDetail config_details = 4;
+}
+
+// API: /User/ApplyConfigToAgentGroup/
+
+message ApplyConfigToAgentGroupRequest {
+    string request_id = 1;
+    string config_name = 2;
+    string group_name = 3;
+}
+
+message ApplyConfigToAgentGroupResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+}
+
+// API: /User/RemoveConfigFromAgentGroup/
+
+message RemoveConfigFromAgentGroupRequest {
+    string request_id = 1;
+    string config_name = 2;
+    string group_name = 3;
+}
+
+message RemoveConfigFromAgentGroupResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+}
+
+// API: /User/GetAppliedConfigsForAgentGroup/
+
+message GetAppliedConfigsForAgentGroupRequest {
+    string request_id = 1;
+    string group_name = 2;
+}
+
+message GetAppliedConfigsForAgentGroupResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+
+    repeated string config_names = 4;
+}
+
+// API: /User/GetAppliedAgentGroups/
+
+message GetAppliedAgentGroupsRequest {
+    string request_id = 1;
+    string config_name = 2;
+}
+
+message GetAppliedAgentGroupsResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+
+    repeated string agent_group_names = 4;
+}
+
+// API: /User/ListAgents/
+
+message ListAgentsRequest {
+    string request_id = 1;
+    string group_name = 2;
+}
+
+message ListAgentsResponse {
+    string response_id = 1;
+    RespCode code = 2;
+    string message = 3;
+
+    repeated Agent agents = 4;
+}
\ No newline at end of file
diff --git a/config_server/protocol/v2/README.md b/config_server/v2/protocol/v2/README.md
similarity index 97%
rename from config_server/protocol/v2/README.md
rename to config_server/v2/protocol/v2/README.md
index 54b7bd088b..7d588a5348 100644
--- a/config_server/protocol/v2/README.md
+++ b/config_server/v2/protocol/v2/README.md
@@ -75,7 +75,7 @@
         // The Agent can accept pipeline configuration from the Server.
         AcceptsPipelineConfig          = 0x00000001;
         // The Agent can accept process configuration from the Server.
-        AcceptsProcessConfig           = 0x00000002;
+        AcceptsInstanceConfig           = 0x00000002;
         // The Agent can accept custom command from the Server.
         AcceptsCustomCommand           = 0x00000004;
 
@@ -127,7 +127,7 @@
         // The Server can remember pipeline config status.
         RembersPipelineConfigStatus        = 0x00000002;
         // The Server can remember process config status.
-        RembersProcessConfigStatus         = 0x00000004;
+        RembersInstanceConfigStatus         = 0x00000004;
         // The Server can remember custom command status.
         RembersCustomCommandStatus         = 0x00000008;
 
@@ -150,7 +150,7 @@
         // restarted and lost state).
         ReportFullState           = 0x00000001;
         FetchPipelineConfigDetail = 0x00000002;
-        FetchProcessConfigDetail  = 0x00000004;
+        FetchInstanceConfigDetail  = 0x00000004;
         // bits before 2^16 (inclusive) are reserved for future official fields
     }
 
@@ -198,9 +198,9 @@ Client:直接从response中获得detail,应用成功后下次心跳需要上
 
 若Server的响应不包含detail
 
-Client:根据process\_config\_updates的信息构造FetchProcessConfigRequest
+Client:根据process\_config\_updates的信息构造FetchInstanceConfigRequest
 
-Server:返回FetchProcessConfigResponse
+Server:返回FetchInstanceConfigResponse
 
 Client获取到多个进程配置时,自动合并,若产生冲突默认行为是未定义。
 
diff --git a/config_server/v2/protocol/v2/agent.proto b/config_server/v2/protocol/v2/agent.proto
new file mode 100644
index 0000000000..d9e52a883f
--- /dev/null
+++ b/config_server/v2/protocol/v2/agent.proto
@@ -0,0 +1,168 @@
+syntax = "proto3";
+option go_package = "/protov2;";
+
+message AgentGroupTag {
+    string name = 1;
+    string value = 2;
+}
+
+enum ConfigStatus {
+    // The value of status field is not set.
+    UNSET = 0;
+    // Agent is currently applying the remote config that it received earlier.
+    APPLYING = 1;
+    // Remote config was successfully applied by the Agent.
+    APPLIED = 2;
+    // Agent tried to apply the config received earlier, but it failed.
+    // See error_message for more details.
+    FAILED = 3;
+}
+
+// Define the Config information carried in the request
+message ConfigInfo {
+    string name = 1;         // Required, Config's unique identification
+    int64 version = 2;       // Required, Config's version number or hash code
+    ConfigStatus status = 3; // Config's status
+    string message = 4;      // Optional error message
+}
+
+// Define the Command information carried in the request
+message CommandInfo {
+    string type = 1;         // Command's type
+    string name = 2;         // Required, Command's unique identification
+    ConfigStatus status = 3; // Command's status
+    string message = 4;      // Optional error message
+}
+
+// Define Agent's basic attributes
+message AgentAttributes {
+    bytes version = 1;                 // Agent's version
+    bytes ip = 2;                      // Agent's ip
+    bytes hostname = 3;                // Agent's hostname
+    bytes hostid = 4;                  // Agent's hostid  https://opentelemetry.io/docs/specs/semconv/attributes-registry/host/
+    map<string, bytes> extras = 100;   // Agent's other attributes
+    // before 100 (inclusive) are reserved for future official fields
+}
+
+enum AgentCapabilities {
+    // The capabilities field is unspecified.
+    UnspecifiedAgentCapability = 0;
+    // The Agent can accept pipeline configuration from the Server.
+    AcceptsPipelineConfig          = 0x00000001;
+    // The Agent can accept instance configuration from the Server.
+    AcceptsInstanceConfig           = 0x00000002;
+    // The Agent can accept custom command from the Server.
+    AcceptsCustomCommand           = 0x00000004;
+
+    // Add new capabilities here, continuing with the least significant unused bit.
+}
+
+enum RequestFlags {
+    RequestFlagsUnspecified = 0;
+
+    // Flags is a bit mask. Values below define individual bits.
+
+    // Must be set if this request contains full state
+    FullState               = 0x00000001;
+    // bits before 2^16 (inclusive) are reserved for future official fields
+}
+
+// API: /Agent/Heartbeat
+
+// Agent sends requests to the ConfigServer to get config updates and receive commands.
+message HeartbeatRequest {
+    bytes request_id = 1;
+    uint64 sequence_num = 2;                    // Increment every request, for server to check sync status
+    uint64 capabilities = 3;                    // Bitmask of flags defined by AgentCapabilities enum
+    bytes instance_id = 4;                      // Required, Agent's unique identification, consistent throughout the process lifecycle
+    string agent_type = 5;                      // Required, Agent's type(ilogtail, ..)
+    AgentAttributes attributes = 6;             // Agent's basic attributes
+    repeated AgentGroupTag tags =  7;           // Agent's tags
+    string running_status = 8;                  // Human readable running status
+    int64 startup_time = 9;                     // Required, Agent's startup time
+    repeated ConfigInfo pipeline_configs = 10;  // Information about the current PIPELINE_CONFIG held by the Agent
+    repeated ConfigInfo instance_configs = 11;  // Information about the current AGENT_CONFIG held by the Agent
+    repeated CommandInfo custom_commands = 12;  // Information about command history
+    uint64 flags = 13;                          // Predefined command flag
+    bytes opaque = 14;                          // Opaque data for extension
+    // before 100 (inclusive) are reserved for future official fields
+}
+
+// Define Config's detail
+message ConfigDetail {
+    string name = 1;        // Required, Config's unique identification
+    int64 version = 2;      // Required, Config's version number or hash code
+    bytes detail = 3;       // Required, Config's detail
+}
+
+message CommandDetail {
+    string type = 1;                // Required, Command type
+    string name = 2;                // Required, Command name
+    bytes detail = 3;               // Required, Command's detail
+    int64 expire_time = 4;          // After which the command can be safely removed from history
+}
+
+enum ServerCapabilities {
+    // The capabilities field is unspecified.
+    UnspecifiedServerCapability = 0;
+    // The Server can remember agent attributes.
+    RembersAttribute                   = 0x00000001;
+    // The Server can remember pipeline config status.
+    RembersPipelineConfigStatus        = 0x00000002;
+    // The Server can remember instance config status.
+    RembersInstanceConfigStatus         = 0x00000004;
+    // The Server can remember custom command status.
+    RembersCustomCommandStatus         = 0x00000008;
+
+    // bits before 2^16 (inclusive) are reserved for future official fields
+}
+
+enum ResponseFlags {
+    ResponseFlagsUnspecified = 0;
+
+    // Flags is a bit mask. Values below define individual bits.
+
+    // ReportFullState flag can be used by the Server if the Client did not include
+    // some sub-message in the last AgentToServer message (which is an allowed
+    // optimization) but the Server detects that it does not have it (e.g. was
+    // restarted and lost state).
+    ReportFullState           = 0x00000001;
+    FetchPipelineConfigDetail = 0x00000002;
+    FetchInstanceConfigDetail = 0x00000004;
+    // bits before 2^16 (inclusive) are reserved for future official fields
+}
+
+// ConfigServer's response to Agent's request
+message HeartbeatResponse {
+    bytes request_id = 1;
+    CommonResponse common_response = 2;                  // Set common response
+    uint64 capabilities = 3;                            // Bitmask of flags defined by ServerCapabilities enum
+
+    repeated ConfigDetail pipeline_config_updates = 4;  // Agent's pipeline config update status
+    repeated ConfigDetail instance_config_updates = 5;  // Agent's instance config update status
+    repeated CommandDetail custom_command_updates = 6;  // Agent's commands updates
+    uint64 flags = 7;                                   // Predefined command flag
+    bytes opaque = 8;                                   // Opaque data for extension
+}
+
+// API: /Agent/FetchPipelineConfig/
+// API: /Agent/FetchInstanceConfig/
+// Agent request to ConfigServer, pulling details of the config
+message FetchConfigRequest {
+    bytes request_id = 1;
+    bytes instance_id = 2;                 // Agent's unique identification
+    repeated ConfigInfo req_configs = 3;   // Config's name and version/hash
+}
+
+// ConfigServer response to Agent's request
+message FetchConfigResponse {
+    bytes request_id = 1;
+    CommonResponse common_response = 2;
+    repeated ConfigDetail config_details = 3;   // config detail
+}
+
+message CommonResponse
+{
+    int32 status = 1;
+    bytes error_message = 2;
+}
\ No newline at end of file
diff --git a/config_server/v2/protocol/v2/user.proto b/config_server/v2/protocol/v2/user.proto
new file mode 100644
index 0000000000..5fe277fe43
--- /dev/null
+++ b/config_server/v2/protocol/v2/user.proto
@@ -0,0 +1,221 @@
+syntax = "proto3";
+option go_package = "/protov2;";
+import "agent.proto";
+
+
+message Agent{
+  uint64 capabilities = 1;                    // Bitmask of flags defined by AgentCapabilities enum
+  bytes instance_id = 2;                      // Required, Agent's unique identification, consistent throughout the process lifecycle
+  string agent_type = 3;                      // Required, Agent's type(ilogtail, ..)
+  AgentAttributes attributes = 4;             // Agent's basic attributes
+  string running_status = 5;                  // Human readable running status
+  int64 startup_time = 6;                     // Required, Agent's startup time
+}
+
+
+// API: /User/CreateAgentGroup
+
+message CreateAgentGroupRequest {
+  bytes request_id = 1;
+  AgentGroupTag agent_group = 2;
+}
+
+message CreateAgentGroupResponse {
+  bytes request_id = 1;
+  CommonResponse common_response=2;
+}
+
+// API: /User/UpdateAgentGroup
+
+message UpdateAgentGroupRequest {
+  bytes request_id = 1;
+  AgentGroupTag agent_group = 2;
+}
+
+message UpdateAgentGroupResponse {
+  bytes request_id = 1;
+  CommonResponse common_response=2;
+}
+
+// API: /User/DeleteAgentGroup/
+
+message DeleteAgentGroupRequest {
+  bytes request_id = 1;
+  string group_name = 2;
+}
+
+message DeleteAgentGroupResponse {
+  bytes request_id = 1;
+  CommonResponse common_response=2;
+}
+
+// API: /User/GetAgentGroup/
+
+message GetAgentGroupRequest {
+  bytes request_id = 1;
+  string group_name = 2;
+}
+
+message GetAgentGroupResponse {
+  bytes request_id = 1;
+  CommonResponse common_response=2;
+  AgentGroupTag agent_group = 3;
+}
+
+// API: /User/ListAgentGroups/
+
+message ListAgentGroupsRequest {
+  bytes request_id = 1;
+}
+
+message ListAgentGroupsResponse {
+  bytes request_id = 1;
+  CommonResponse common_response=2;
+
+  repeated AgentGroupTag agent_groups = 4;
+}
+
+// API: /User/CreatePipelineConfig
+// API: /User/CreateInstanceConfig
+message CreateConfigRequest {
+  bytes request_id = 1;
+  ConfigDetail config_detail = 2;
+}
+
+message CreateConfigResponse {
+  bytes request_id = 1;
+  CommonResponse common_response =2;
+}
+
+// API: /User/UpdatePipelineConfig
+// API: /User/UpdateInstanceConfig
+message UpdateConfigRequest {
+  bytes request_id = 1;
+  ConfigDetail config_detail = 2;
+}
+
+message UpdateConfigResponse {
+  bytes request_id = 1;
+  CommonResponse common_response=2;
+}
+
+// API: /User/DeletePipelineConfig
+// API: /User/DeleteInstanceConfig
+message DeleteConfigRequest {
+  bytes request_id = 1;
+  string config_name = 2;
+}
+
+message DeleteConfigResponse {
+  bytes request_id = 1;
+  CommonResponse common_response=2;
+}
+
+// API: /User/GetPipelineConfig
+// API: /User/GetInstanceConfig
+message GetConfigRequest {
+  bytes request_id = 1;
+  string config_name = 2;
+}
+
+message GetConfigResponse {
+  bytes request_id = 1;
+  CommonResponse common_response=2;
+
+  ConfigDetail config_detail = 3;
+}
+
+// API: /User/GetPipelineConfigStatusList
+// API: /User/GetInstanceConfigStatusList
+message GetConfigStatusListRequest{
+  bytes request_id = 1;
+  bytes instance_id = 2;
+}
+
+message GetConfigStatusListResponse{
+  bytes request_id = 1;
+  CommonResponse common_response = 2;
+  repeated ConfigInfo config_status = 3;
+}
+
+// API: /User/ListPipelineConfigs
+// API: /User/ListInstanceConfigs
+message ListConfigsRequest {
+  bytes request_id = 1;
+}
+
+message ListConfigsResponse {
+  bytes request_id = 1;
+  CommonResponse common_response = 2;
+
+  repeated ConfigDetail config_details = 3;
+}
+
+// API: /User/ApplyPipelineConfigToAgentGroup
+// API: /User/ApplyInstanceConfigToAgentGroup
+message ApplyConfigToAgentGroupRequest {
+  bytes request_id = 1;
+  string config_name = 2;
+  string group_name = 3;
+}
+
+message ApplyConfigToAgentGroupResponse {
+  bytes request_id = 1;
+  CommonResponse common_response = 2;
+}
+
+// API: /User/RemovePipelineConfigFromAgentGroup/
+// API: /User/RemoveInstanceConfigFromAgentGroup/
+message RemoveConfigFromAgentGroupRequest {
+  bytes request_id = 1;
+  string config_name = 2;
+  string group_name = 3;
+}
+
+message RemoveConfigFromAgentGroupResponse {
+  bytes request_id = 1;
+  CommonResponse common_response = 2;
+}
+
+
+// API: /User/GetAppliedPipelineConfigsForAgentGroup/
+// API: /User/GetAppliedInstanceConfigsForAgentGroup/
+message GetAppliedConfigsForAgentGroupRequest {
+  bytes request_id = 1;
+  string group_name = 2;
+}
+
+message GetAppliedConfigsForAgentGroupResponse {
+  bytes request_id = 1;
+  CommonResponse common_response = 2;
+
+  repeated string config_names = 4;
+}
+
+// API: /User/GetAppliedAgentGroupsWithPipelineConfig/
+// API: /User/GetAppliedAgentGroupsWithInstanceConfig/
+message GetAppliedAgentGroupsRequest {
+  bytes request_id = 1;
+  string config_name = 2;
+}
+
+message GetAppliedAgentGroupsResponse {
+  bytes request_id = 1;
+  CommonResponse common_response = 2;
+
+  repeated string agent_group_names = 3;
+}
+
+// API: /User/ListAgents/
+
+message ListAgentsRequest {
+  bytes request_id = 1;
+  string group_name = 2;
+}
+
+message ListAgentsResponse {
+  bytes request_id = 1;
+  CommonResponse common_response = 2;
+
+  repeated Agent agents = 3;
+}
\ No newline at end of file
diff --git a/config_server/service/.gitignore b/config_server/v2/service/.gitignore
similarity index 100%
rename from config_server/service/.gitignore
rename to config_server/v2/service/.gitignore
diff --git a/config_server/service/Dockerfile b/config_server/v2/service/Dockerfile
similarity index 100%
rename from config_server/service/Dockerfile
rename to config_server/v2/service/Dockerfile
diff --git a/config_server/service/Dockerfile-dev b/config_server/v2/service/Dockerfile-dev
similarity index 100%
rename from config_server/service/Dockerfile-dev
rename to config_server/v2/service/Dockerfile-dev
diff --git a/config_server/service/README.md b/config_server/v2/service/README.md
similarity index 100%
rename from config_server/service/README.md
rename to config_server/v2/service/README.md
diff --git a/config_server/service/cmd/config/prod/databaseConfig.json b/config_server/v2/service/cmd/config/prod/databaseConfig.json
similarity index 100%
rename from config_server/service/cmd/config/prod/databaseConfig.json
rename to config_server/v2/service/cmd/config/prod/databaseConfig.json
diff --git a/config_server/service/cmd/config/prod/serverConfig.json b/config_server/v2/service/cmd/config/prod/serverConfig.json
similarity index 100%
rename from config_server/service/cmd/config/prod/serverConfig.json
rename to config_server/v2/service/cmd/config/prod/serverConfig.json
diff --git a/config_server/service/cmd/main.go b/config_server/v2/service/cmd/main.go
similarity index 100%
rename from config_server/service/cmd/main.go
rename to config_server/v2/service/cmd/main.go
diff --git a/config_server/service/common/api_error.go b/config_server/v2/service/common/api_error.go
similarity index 100%
rename from config_server/service/common/api_error.go
rename to config_server/v2/service/common/api_error.go
diff --git a/config_server/service/common/http_status.go b/config_server/v2/service/common/http_status.go
similarity index 100%
rename from config_server/service/common/http_status.go
rename to config_server/v2/service/common/http_status.go
diff --git a/config_server/service/common/log.go b/config_server/v2/service/common/log.go
similarity index 100%
rename from config_server/service/common/log.go
rename to config_server/v2/service/common/log.go
diff --git a/config_server/service/common/result.go b/config_server/v2/service/common/result.go
similarity index 100%
rename from config_server/service/common/result.go
rename to config_server/v2/service/common/result.go
diff --git a/config_server/service/config/gorm.go b/config_server/v2/service/config/gorm.go
similarity index 100%
rename from config_server/service/config/gorm.go
rename to config_server/v2/service/config/gorm.go
diff --git a/config_server/service/config/server.go b/config_server/v2/service/config/server.go
similarity index 100%
rename from config_server/service/config/server.go
rename to config_server/v2/service/config/server.go
diff --git a/config_server/service/entity/agent.go b/config_server/v2/service/entity/agent.go
similarity index 100%
rename from config_server/service/entity/agent.go
rename to config_server/v2/service/entity/agent.go
diff --git a/config_server/service/entity/agent_group.go b/config_server/v2/service/entity/agent_group.go
similarity index 100%
rename from config_server/service/entity/agent_group.go
rename to config_server/v2/service/entity/agent_group.go
diff --git a/config_server/service/entity/base.go b/config_server/v2/service/entity/base.go
similarity index 100%
rename from config_server/service/entity/base.go
rename to config_server/v2/service/entity/base.go
diff --git a/config_server/service/entity/command.go b/config_server/v2/service/entity/command.go
similarity index 100%
rename from config_server/service/entity/command.go
rename to config_server/v2/service/entity/command.go
diff --git a/config_server/service/entity/instance_config.go b/config_server/v2/service/entity/instance_config.go
similarity index 100%
rename from config_server/service/entity/instance_config.go
rename to config_server/v2/service/entity/instance_config.go
diff --git a/config_server/service/entity/pipeline_config.go b/config_server/v2/service/entity/pipeline_config.go
similarity index 100%
rename from config_server/service/entity/pipeline_config.go
rename to config_server/v2/service/entity/pipeline_config.go
diff --git a/config_server/service/go.mod b/config_server/v2/service/go.mod
similarity index 91%
rename from config_server/service/go.mod
rename to config_server/v2/service/go.mod
index 6f14b84fc4..2acef0363a 100644
--- a/config_server/service/go.mod
+++ b/config_server/v2/service/go.mod
@@ -4,6 +4,7 @@ go 1.19
 
 require (
 	github.com/gin-gonic/gin v1.10.0
+	github.com/smartystreets/goconvey v1.8.1
 	google.golang.org/protobuf v1.34.2
 	gorm.io/driver/mysql v1.5.7
 	gorm.io/driver/postgres v1.5.9
@@ -26,6 +27,7 @@ require (
 	github.com/goccy/go-json v0.10.2 // indirect
 	github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
 	github.com/golang-sql/sqlexp v0.1.0 // indirect
+	github.com/gopherjs/gopherjs v1.17.2 // indirect
 	github.com/jackc/pgpassfile v1.0.0 // indirect
 	github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
 	github.com/jackc/pgx/v5 v5.5.5 // indirect
@@ -33,6 +35,7 @@ require (
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/jtolds/gls v4.20.0+incompatible // indirect
 	github.com/klauspost/cpuid/v2 v2.2.7 // indirect
 	github.com/kr/text v0.2.0 // indirect
 	github.com/leodido/go-urn v1.4.0 // indirect
@@ -43,6 +46,7 @@ require (
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/pelletier/go-toml/v2 v2.2.2 // indirect
 	github.com/rogpeppe/go-internal v1.12.0 // indirect
+	github.com/smarty/assertions v1.15.0 // indirect
 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
 	github.com/ugorji/go/codec v1.2.12 // indirect
 	golang.org/x/arch v0.8.0 // indirect
diff --git a/config_server/service/go.sum b/config_server/v2/service/go.sum
similarity index 95%
rename from config_server/service/go.sum
rename to config_server/v2/service/go.sum
index b1673ae883..648bbf6187 100644
--- a/config_server/service/go.sum
+++ b/config_server/v2/service/go.sum
@@ -55,10 +55,12 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0kt
 github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
 github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
 github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
-github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
+github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
 github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
 github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
 github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
@@ -83,6 +85,8 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
 github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
 github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
@@ -115,6 +119,10 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
 github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
+github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
+github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
+github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
+github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -199,7 +207,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
 google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/config_server/service/handler/agent.go b/config_server/v2/service/handler/agent.go
similarity index 100%
rename from config_server/service/handler/agent.go
rename to config_server/v2/service/handler/agent.go
diff --git a/config_server/service/handler/agent_group.go b/config_server/v2/service/handler/agent_group.go
similarity index 100%
rename from config_server/service/handler/agent_group.go
rename to config_server/v2/service/handler/agent_group.go
diff --git a/config_server/service/handler/common.go b/config_server/v2/service/handler/common.go
similarity index 90%
rename from config_server/service/handler/common.go
rename to config_server/v2/service/handler/common.go
index e171570dd4..b1bd0da167 100644
--- a/config_server/service/handler/common.go
+++ b/config_server/v2/service/handler/common.go
@@ -9,9 +9,9 @@ import (
 	"strings"
 )
 
-type ProtobufFunc[T any, R any] func(request *T, response *R) error
+type ProtobufFunc[T, R any] func(request *T, response *R) error
 
-func ProtobufHandler[T any, R any](handler ProtobufFunc[T, R]) gin.HandlerFunc {
+func ProtobufHandler[T, R any](handler ProtobufFunc[T, R]) gin.HandlerFunc {
 	return func(c *gin.Context) {
 		var err error
 		request := new(T)
diff --git a/config_server/service/handler/instance_config.go b/config_server/v2/service/handler/instance_config.go
similarity index 100%
rename from config_server/service/handler/instance_config.go
rename to config_server/v2/service/handler/instance_config.go
diff --git a/config_server/service/handler/pipeline_config.go b/config_server/v2/service/handler/pipeline_config.go
similarity index 100%
rename from config_server/service/handler/pipeline_config.go
rename to config_server/v2/service/handler/pipeline_config.go
diff --git a/config_server/service/manager/agent.go b/config_server/v2/service/manager/agent.go
similarity index 100%
rename from config_server/service/manager/agent.go
rename to config_server/v2/service/manager/agent.go
diff --git a/config_server/service/manager/agent_group.go b/config_server/v2/service/manager/agent_group.go
similarity index 100%
rename from config_server/service/manager/agent_group.go
rename to config_server/v2/service/manager/agent_group.go
diff --git a/config_server/service/manager/instance_config.go b/config_server/v2/service/manager/instance_config.go
similarity index 100%
rename from config_server/service/manager/instance_config.go
rename to config_server/v2/service/manager/instance_config.go
diff --git a/config_server/service/manager/pipeline_config.go b/config_server/v2/service/manager/pipeline_config.go
similarity index 100%
rename from config_server/service/manager/pipeline_config.go
rename to config_server/v2/service/manager/pipeline_config.go
diff --git a/config_server/service/manager/state/agent.go b/config_server/v2/service/manager/state/agent.go
similarity index 100%
rename from config_server/service/manager/state/agent.go
rename to config_server/v2/service/manager/state/agent.go
diff --git a/config_server/service/manager/state/common.go b/config_server/v2/service/manager/state/common.go
similarity index 100%
rename from config_server/service/manager/state/common.go
rename to config_server/v2/service/manager/state/common.go
diff --git a/config_server/service/manager/state/request.go b/config_server/v2/service/manager/state/request.go
similarity index 100%
rename from config_server/service/manager/state/request.go
rename to config_server/v2/service/manager/state/request.go
diff --git a/config_server/service/manager/state/response.go b/config_server/v2/service/manager/state/response.go
similarity index 100%
rename from config_server/service/manager/state/response.go
rename to config_server/v2/service/manager/state/response.go
diff --git a/config_server/service/manager/state/server.go b/config_server/v2/service/manager/state/server.go
similarity index 100%
rename from config_server/service/manager/state/server.go
rename to config_server/v2/service/manager/state/server.go
diff --git a/config_server/service/protov2/README.md b/config_server/v2/service/protov2/README.md
similarity index 100%
rename from config_server/service/protov2/README.md
rename to config_server/v2/service/protov2/README.md
diff --git a/config_server/service/protov2/agent.pb.go b/config_server/v2/service/protov2/agent.pb.go
similarity index 100%
rename from config_server/service/protov2/agent.pb.go
rename to config_server/v2/service/protov2/agent.pb.go
diff --git a/config_server/service/protov2/user.pb.go b/config_server/v2/service/protov2/user.pb.go
similarity index 100%
rename from config_server/service/protov2/user.pb.go
rename to config_server/v2/service/protov2/user.pb.go
diff --git a/config_server/service/repository/agent.go b/config_server/v2/service/repository/agent.go
similarity index 100%
rename from config_server/service/repository/agent.go
rename to config_server/v2/service/repository/agent.go
diff --git a/config_server/service/repository/agent_group.go b/config_server/v2/service/repository/agent_group.go
similarity index 100%
rename from config_server/service/repository/agent_group.go
rename to config_server/v2/service/repository/agent_group.go
diff --git a/config_server/service/repository/base.go b/config_server/v2/service/repository/base.go
similarity index 100%
rename from config_server/service/repository/base.go
rename to config_server/v2/service/repository/base.go
diff --git a/config_server/service/repository/instance_config.go b/config_server/v2/service/repository/instance_config.go
similarity index 100%
rename from config_server/service/repository/instance_config.go
rename to config_server/v2/service/repository/instance_config.go
diff --git a/config_server/service/repository/pipeline_config.go b/config_server/v2/service/repository/pipeline_config.go
similarity index 100%
rename from config_server/service/repository/pipeline_config.go
rename to config_server/v2/service/repository/pipeline_config.go
diff --git a/config_server/service/router/router.go b/config_server/v2/service/router/router.go
similarity index 100%
rename from config_server/service/router/router.go
rename to config_server/v2/service/router/router.go
diff --git a/config_server/service/service/agent.go b/config_server/v2/service/service/agent.go
similarity index 100%
rename from config_server/service/service/agent.go
rename to config_server/v2/service/service/agent.go
diff --git a/config_server/service/service/agent_group.go b/config_server/v2/service/service/agent_group.go
similarity index 96%
rename from config_server/service/service/agent_group.go
rename to config_server/v2/service/service/agent_group.go
index 2784cce264..00abbfb26d 100644
--- a/config_server/service/service/agent_group.go
+++ b/config_server/v2/service/service/agent_group.go
@@ -38,7 +38,7 @@ func DeleteAgentGroup(req *proto.DeleteAgentGroupRequest, res *proto.DeleteAgent
 		return common.ValidateErrorWithMsg("required field groupName could not be null")
 	}
 	if req.GroupName == entity.AgentGroupDefaultValue {
-		return common.ServerErrorWithMsg(common.AgentGroupNotExist, "%s can not be deleted", entity.AgentGroupDefaultValue)
+		return common.ServerErrorWithMsg(common.InvalidParameter, "%s can not be deleted", entity.AgentGroupDefaultValue)
 	}
 	err := repository.DeleteAgentGroup(agentGroupName)
 	return common.SystemError(err)
diff --git a/config_server/service/service/instance_config.go b/config_server/v2/service/service/instance_config.go
similarity index 98%
rename from config_server/service/service/instance_config.go
rename to config_server/v2/service/service/instance_config.go
index eb817b5f6c..7b3d480845 100644
--- a/config_server/service/service/instance_config.go
+++ b/config_server/v2/service/service/instance_config.go
@@ -14,9 +14,10 @@ func CreateInstanceConfig(req *proto.CreateConfigRequest, res *proto.CreateConfi
 		return common.ValidateErrorWithMsg("required field configName could not be null")
 	}
 
-	if configDetail.Version == 0 {
-		return common.ValidateErrorWithMsg("required field version could not be null")
+	if configDetail.Version <= 0 {
+		return common.ValidateErrorWithMsg("required field version could not less than 0")
 	}
+
 	instanceConfig := entity.ParseProtoInstanceConfig2InstanceConfig(configDetail)
 	err := repository.CreateInstanceConfig(instanceConfig)
 	return common.SystemError(err)
diff --git a/config_server/service/service/pipeline_config.go b/config_server/v2/service/service/pipeline_config.go
similarity index 98%
rename from config_server/service/service/pipeline_config.go
rename to config_server/v2/service/service/pipeline_config.go
index b09149b2be..9a19040563 100644
--- a/config_server/service/service/pipeline_config.go
+++ b/config_server/v2/service/service/pipeline_config.go
@@ -14,8 +14,8 @@ func CreatePipelineConfig(req *proto.CreateConfigRequest, res *proto.CreateConfi
 		return common.ValidateErrorWithMsg("required field configName could not be null")
 	}
 
-	if configDetail.Version == 0 {
-		return common.ValidateErrorWithMsg("required field version could not be null")
+	if configDetail.Version <= 0 {
+		return common.ValidateErrorWithMsg("required field version could not less than 0")
 	}
 
 	pipelineConfig := entity.ParseProtoPipelineConfig2PipelineConfig(configDetail)
diff --git a/config_server/service/store/gorm.go b/config_server/v2/service/store/gorm.go
similarity index 100%
rename from config_server/service/store/gorm.go
rename to config_server/v2/service/store/gorm.go
diff --git a/config_server/service/store/gorm_test.go b/config_server/v2/service/store/gorm_test.go
similarity index 100%
rename from config_server/service/store/gorm_test.go
rename to config_server/v2/service/store/gorm_test.go
diff --git a/config_server/service/store/store.go b/config_server/v2/service/store/store.go
similarity index 100%
rename from config_server/service/store/store.go
rename to config_server/v2/service/store/store.go
diff --git a/config_server/v2/service/test/api_test.go b/config_server/v2/service/test/api_test.go
new file mode 100644
index 0000000000..f86a8cea5c
--- /dev/null
+++ b/config_server/v2/service/test/api_test.go
@@ -0,0 +1,581 @@
+package test
+
+import (
+	"config-server/common"
+	"config-server/protov2"
+	"config-server/test/request"
+	"fmt"
+	. "github.com/smartystreets/goconvey/convey"
+	"math/rand"
+	"testing"
+	"time"
+)
+
+const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+
+func generateRandomNum(length int) []byte {
+	seededRand := rand.New(rand.NewSource(time.Now().UnixNano()))
+	b := make([]byte, length)
+	for i := range b {
+		b[i] = charset[seededRand.Intn(len(charset))]
+	}
+	return b
+}
+
+func TestBaseAgent(t *testing.T) {
+	requestId := generateRandomNum(10)
+	Convey("Test delete AgentGroup.", t, func() {
+		fmt.Print("\n" + "Test delete default. ")
+		{
+			res, _ := request.DeleteAgentGroup(requestId, "default")
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, common.InvalidParameter.Code)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, common.InvalidParameter.Message)
+
+		}
+	})
+}
+
+func TestBasePipelineConfig(t *testing.T) {
+
+	var configLength int
+
+	Convey("Test create PipelineConfig.", t, func() {
+
+		fmt.Print("\n" + "Test get all configs. ")
+		{
+			requestId := generateRandomNum(10)
+			res, _ := request.GetAllPipelineConfig(requestId)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			configLength = len(res.ConfigDetails)
+		}
+
+		fmt.Print("\n" + "Test create config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			detail := &protov2.ConfigDetail{
+				Name:   "config-1",
+				Detail: []byte("Detail for test config-1"),
+			}
+			res, _ := request.CreatePipelineConfig(requestId, detail)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, common.InvalidParameter.Code)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, common.InvalidParameter.Message)
+		}
+
+		fmt.Print("\n" + "Test create config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			detail := &protov2.ConfigDetail{
+				Name:    "config-1",
+				Version: 1,
+				Detail:  []byte("Detail for test config-1"),
+			}
+			res, _ := request.CreatePipelineConfig(requestId, detail)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+		}
+
+		fmt.Print("\n" + "Test get config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-1"
+
+			res, _ := request.GetPipelineConfig(requestId, configName)
+
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			So(res.ConfigDetail.Name, ShouldEqual, configName)
+			So(res.ConfigDetail.Version, ShouldEqual, 1)
+			So(string(res.ConfigDetail.Detail), ShouldEqual, "Detail for test config-1")
+		}
+
+		fmt.Print("\n" + "Test create config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			detail := &protov2.ConfigDetail{
+				Name:    "config-1",
+				Version: 1,
+				Detail:  []byte("Detail for test config-1"),
+			}
+			res, _ := request.CreatePipelineConfig(requestId, detail)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, common.ConfigAlreadyExist.Code)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, common.ConfigAlreadyExist.Message)
+		}
+
+		fmt.Print("\n" + "Test get all configs. ")
+		{
+			requestId := generateRandomNum(10)
+			res, _ := request.GetAllPipelineConfig(requestId)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			So(len(res.ConfigDetails), ShouldEqual, configLength+1)
+		}
+
+		fmt.Print("\n" + "Test create config-2. ")
+		{
+			requestId := generateRandomNum(10)
+			detail := &protov2.ConfigDetail{
+				Name:    "config-2",
+				Version: 1,
+				Detail:  []byte("Detail for test config-2"),
+			}
+			res, _ := request.CreatePipelineConfig(requestId, detail)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+
+		}
+
+		fmt.Print("\n" + "Test create config-2. ")
+		{
+			requestId := generateRandomNum(10)
+			detail := &protov2.ConfigDetail{
+				Name:    "config-2",
+				Version: 1,
+				Detail:  []byte("Detail for test config-2"),
+			}
+			res, _ := request.CreatePipelineConfig(requestId, detail)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, common.ConfigAlreadyExist.Code)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, common.ConfigAlreadyExist.Message)
+		}
+
+		fmt.Print("\n" + "Test get config-2. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-2"
+
+			res, _ := request.GetPipelineConfig(requestId, configName)
+
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			So(res.ConfigDetail.Name, ShouldEqual, configName)
+			So(res.ConfigDetail.Version, ShouldEqual, 1)
+			So(string(res.ConfigDetail.Detail), ShouldEqual, "Detail for test config-2")
+		}
+
+	})
+
+	Convey("Test update PipelineConfig.", t, func() {
+
+		fmt.Print("\n" + "Test update config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			detail := &protov2.ConfigDetail{
+				Name:    "config-1",
+				Version: 1,
+				Detail:  []byte("Detail for update config-1"),
+			}
+			res, _ := request.UpdatePipelineConfig(requestId, detail)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+		}
+
+		fmt.Print("\n" + "Test get config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-1"
+
+			res, _ := request.GetPipelineConfig(requestId, configName)
+
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			So(res.ConfigDetail.Name, ShouldEqual, configName)
+			So(res.ConfigDetail.Version, ShouldEqual, 2)
+			So(string(res.ConfigDetail.Detail), ShouldEqual, "Detail for update config-1")
+		}
+
+		fmt.Print("\n" + "Test update config-2. ")
+		{
+			requestId := generateRandomNum(10)
+			detail := &protov2.ConfigDetail{
+				Name:    "config-2",
+				Version: 1,
+				Detail:  []byte("Detail for update config-2"),
+			}
+			res, _ := request.UpdatePipelineConfig(requestId, detail)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+		}
+
+		fmt.Print("\n" + "Test get config-2. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-2"
+
+			res, _ := request.GetPipelineConfig(requestId, configName)
+
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			So(res.ConfigDetail.Name, ShouldEqual, configName)
+			So(res.ConfigDetail.Version, ShouldEqual, 2)
+			So(string(res.ConfigDetail.Detail), ShouldEqual, "Detail for update config-2")
+		}
+
+		fmt.Print("\n" + "Test get config-3. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-3"
+
+			res, _ := request.GetPipelineConfig(requestId, configName)
+
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, common.ConfigNotExist.Code)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, common.ConfigNotExist.Message)
+		}
+
+		fmt.Print("\n" + "Test get all configs. ")
+		{
+			requestId := generateRandomNum(10)
+			res, _ := request.GetAllPipelineConfig(requestId)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			So(len(res.ConfigDetails), ShouldEqual, configLength+2)
+		}
+
+	})
+
+	Convey("Test delete PipelineConfig.", t, func() {
+
+		fmt.Print("\n" + "Test delete config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-1"
+
+			res, _ := request.DeletePipelineConfig(requestId, configName)
+
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+
+		}
+
+		fmt.Print("\n" + "Test get config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-1"
+
+			res, _ := request.GetPipelineConfig(requestId, configName)
+
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, common.ConfigNotExist.Code)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, common.ConfigNotExist.Message)
+		}
+
+		fmt.Print("\n" + "Test create config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			detail := &protov2.ConfigDetail{
+				Name:    "config-1",
+				Version: 1,
+				Detail:  []byte("Detail for test config-1"),
+			}
+			res, _ := request.CreatePipelineConfig(requestId, detail)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+
+		}
+
+		fmt.Print("\n" + "Test get config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-1"
+
+			res, _ := request.GetPipelineConfig(requestId, configName)
+
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			So(res.ConfigDetail.Name, ShouldEqual, configName)
+			So(res.ConfigDetail.Version, ShouldEqual, 1)
+			So(string(res.ConfigDetail.Detail), ShouldEqual, "Detail for test config-1")
+		}
+
+		fmt.Print("\n" + "Test delete config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-1"
+
+			res, _ := request.DeletePipelineConfig(requestId, configName)
+
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+
+		}
+
+		fmt.Print("\n" + "Test get config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-1"
+
+			res, _ := request.GetPipelineConfig(requestId, configName)
+
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, common.ConfigNotExist.Code)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, common.ConfigNotExist.Message)
+		}
+
+		fmt.Print("\n" + "Test delete config-2. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-2"
+
+			res, _ := request.DeletePipelineConfig(requestId, configName)
+
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+
+		}
+
+		fmt.Print("\n" + "Test get config-2. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-2"
+
+			res, _ := request.GetPipelineConfig(requestId, configName)
+
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, common.ConfigNotExist.Code)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, common.ConfigNotExist.Message)
+		}
+
+		fmt.Print("\n" + "Test get all configs. ")
+		{
+			requestId := generateRandomNum(10)
+			res, _ := request.GetAllPipelineConfig(requestId)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			So(len(res.ConfigDetails), ShouldEqual, configLength)
+		}
+	})
+}
+
+func TestOperationBetweenAgentGroupAndPipelineConfig(t *testing.T) {
+	Convey("Test apply PipelineConfig.", t, func() {
+		var defaultGroupConfigLength int
+		fmt.Print("\n" + "Test get default's Configs. ")
+		{
+			requestId := generateRandomNum(10)
+			groupName := "default"
+			res, _ := request.GetAppliedPipelineConfigForAgentGroup(requestId, groupName)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			defaultGroupConfigLength = len(res.ConfigNames)
+		}
+
+		fmt.Print("\n" + "Test create config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			detail := &protov2.ConfigDetail{
+				Name:    "config-1",
+				Version: 1,
+				Detail:  []byte("Detail for test config-1"),
+			}
+			res, _ := request.CreatePipelineConfig(requestId, detail)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+		}
+
+		fmt.Print("\n" + "Test create config-2. ")
+		{
+			requestId := generateRandomNum(10)
+			detail := &protov2.ConfigDetail{
+				Name:    "config-2",
+				Version: 1,
+				Detail:  []byte("Detail for test config-2"),
+			}
+			res, _ := request.CreatePipelineConfig(requestId, detail)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+		}
+
+		fmt.Print("\n" + "Test apply config-1 to default. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-1"
+			groupName := "default"
+			res, _ := request.ApplyPipelineConfig2AgentGroup(requestId, configName, groupName)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+		}
+
+		fmt.Print("\n" + "Test get default's Configs. ")
+		{
+			requestId := generateRandomNum(10)
+			groupName := "default"
+			res, _ := request.GetAppliedPipelineConfigForAgentGroup(requestId, groupName)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			So(len(res.ConfigNames), ShouldEqual, defaultGroupConfigLength+1)
+		}
+
+		fmt.Print("\n" + "Test get config-1's AgentGroups. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-1"
+			res, _ := request.GetAppliedAgentGroupForPipelineConfig(requestId, configName)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+		}
+
+		fmt.Print("\n" + "Test apply config-2 to default. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-2"
+			groupName := "default"
+			res, _ := request.ApplyPipelineConfig2AgentGroup(requestId, configName, groupName)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+		}
+
+		fmt.Print("\n" + "Test get default's Configs. ")
+		{
+			requestId := generateRandomNum(10)
+			groupName := "default"
+			res, _ := request.GetAppliedPipelineConfigForAgentGroup(requestId, groupName)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			So(len(res.ConfigNames), ShouldEqual, defaultGroupConfigLength+2)
+		}
+
+	})
+
+	Convey("Test remove PipelineConfig or relationship between config and agentGroup", t, func() {
+		var defaultGroupConfigLength int
+		fmt.Print("\n" + "Test get default's Configs. ")
+		{
+			requestId := generateRandomNum(10)
+			groupName := "default"
+			res, _ := request.GetAppliedPipelineConfigForAgentGroup(requestId, groupName)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			defaultGroupConfigLength = len(res.ConfigNames)
+		}
+
+		fmt.Print("\n" + "Test delete config-1. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-1"
+
+			res, _ := request.DeletePipelineConfig(requestId, configName)
+
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+
+		}
+
+		fmt.Print("\n" + "Test get default's Configs. ")
+		{
+			requestId := generateRandomNum(10)
+			groupName := "default"
+			res, _ := request.GetAppliedPipelineConfigForAgentGroup(requestId, groupName)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			So(len(res.ConfigNames), ShouldEqual, defaultGroupConfigLength-1)
+		}
+
+		fmt.Print("\n" + "Test remove config-2 from default. ")
+		{
+			requestId := generateRandomNum(10)
+			groupName := "default"
+			configName := "config-2"
+			res, _ := request.RemovePipelineConfigFromAgentGroup(requestId, configName, groupName)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+		}
+
+		fmt.Print("\n" + "Test get default's Configs. ")
+		{
+			requestId := generateRandomNum(10)
+			groupName := "default"
+			res, _ := request.GetAppliedPipelineConfigForAgentGroup(requestId, groupName)
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+			So(len(res.ConfigNames), ShouldEqual, defaultGroupConfigLength-2)
+		}
+
+		fmt.Print("\n" + "Test delete config-2. ")
+		{
+			requestId := generateRandomNum(10)
+			configName := "config-2"
+
+			res, _ := request.DeletePipelineConfig(requestId, configName)
+
+			// check
+			So(res.RequestId, ShouldEqual, requestId)
+			So(res.CommonResponse.Status, ShouldEqual, 0)
+			So(string(res.CommonResponse.ErrorMessage), ShouldEqual, "")
+		}
+
+	})
+}
+
+func TestAgentSendMessage(t *testing.T) {
+
+}
+
+func TestAgentFetchPipelineConfig(t *testing.T) {
+
+}
diff --git a/config_server/v2/service/test/cmd/config/dev/databaseConfig.json b/config_server/v2/service/test/cmd/config/dev/databaseConfig.json
new file mode 100644
index 0000000000..6d5ce12582
--- /dev/null
+++ b/config_server/v2/service/test/cmd/config/dev/databaseConfig.json
@@ -0,0 +1,9 @@
+{
+  "type": "mysql",
+  "userName": "root",
+  "password": "123456",
+  "host": "127.0.0.1",
+  "port": 3306,
+  "dbName": "test",
+  "autoMigrate": true
+}
\ No newline at end of file
diff --git a/config_server/v2/service/test/cmd/config/dev/serverConfig.json b/config_server/v2/service/test/cmd/config/dev/serverConfig.json
new file mode 100644
index 0000000000..e9cf7256c5
--- /dev/null
+++ b/config_server/v2/service/test/cmd/config/dev/serverConfig.json
@@ -0,0 +1,14 @@
+{
+  "address": "0.0.0.0:9090",
+  "capabilities": {
+    "rememberAttribute": true,
+    "rememberPipelineConfigStatus": true,
+    "rememberInstanceConfigStatus": true,
+    "rememberCustomCommandStatus": false
+  },
+  "responseFlags": {
+    "fetchPipelineConfigDetail": true,
+    "fetchInstanceConfigDetail": false
+  },
+  "timeLimit": 60
+}
\ No newline at end of file
diff --git a/config_server/v2/service/test/common_test.go b/config_server/v2/service/test/common_test.go
new file mode 100644
index 0000000000..b8939cc5f9
--- /dev/null
+++ b/config_server/v2/service/test/common_test.go
@@ -0,0 +1,10 @@
+package test
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestProto(t *testing.T) {
+	fmt.Println(generateRandomNum(10))
+}
diff --git a/config_server/v2/service/test/request/agent.go b/config_server/v2/service/test/request/agent.go
new file mode 100644
index 0000000000..1e6473e75c
--- /dev/null
+++ b/config_server/v2/service/test/request/agent.go
@@ -0,0 +1,20 @@
+package request
+
+import (
+	"config-server/protov2"
+	"fmt"
+)
+
+func ListAgents(requestId []byte, groupName string) (*protov2.ListAgentsResponse, error) {
+	url := fmt.Sprintf("%s/ListAgents", UserUrlPrefix)
+	req := &protov2.ListAgentsRequest{}
+	res := &protov2.ListAgentsResponse{}
+	req.RequestId = requestId
+	req.GroupName = groupName
+
+	err := sendProtobufRequest(url, POST, req, res)
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
diff --git a/config_server/v2/service/test/request/agent_group.go b/config_server/v2/service/test/request/agent_group.go
new file mode 100644
index 0000000000..1491ec0fdc
--- /dev/null
+++ b/config_server/v2/service/test/request/agent_group.go
@@ -0,0 +1,34 @@
+package request
+
+import (
+	"config-server/protov2"
+	"fmt"
+)
+
+func DeleteAgentGroup(requestId []byte, groupName string) (*protov2.DeleteAgentGroupResponse, error) {
+	url := fmt.Sprintf("%s/DeleteAgentGroup", UserUrlPrefix)
+	req := &protov2.DeleteAgentGroupRequest{}
+	res := &protov2.DeleteAgentGroupResponse{}
+	req.RequestId = requestId
+	req.GroupName = groupName
+
+	err := sendProtobufRequest(url, POST, req, res)
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
+
+func GetAppliedPipelineConfigForAgentGroup(requestId []byte, groupName string) (*protov2.GetAppliedConfigsForAgentGroupResponse, error) {
+	url := fmt.Sprintf("%s/GetAppliedPipelineConfigsForAgentGroup", UserUrlPrefix)
+	req := &protov2.GetAppliedConfigsForAgentGroupRequest{}
+	res := &protov2.GetAppliedConfigsForAgentGroupResponse{}
+	req.RequestId = requestId
+	req.GroupName = groupName
+
+	err := sendProtobufRequest(url, POST, req, res)
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
diff --git a/config_server/service/router/router_test.go b/config_server/v2/service/test/request/common.go
similarity index 56%
rename from config_server/service/router/router_test.go
rename to config_server/v2/service/test/request/common.go
index e3bd46812f..6673d79416 100644
--- a/config_server/service/router/router_test.go
+++ b/config_server/v2/service/test/request/common.go
@@ -1,18 +1,18 @@
-package router
+package request
 
 import (
 	"bytes"
 	"config-server/config"
-	"config-server/protov2"
 	"fmt"
 	"google.golang.org/protobuf/proto"
 	"io"
-	"log"
 	"net/http"
-	"testing"
 )
 
-var UserUrlPrefix = fmt.Sprintf("http://%s/User", config.ServerConfigInstance.Address)
+var (
+	UserUrlPrefix  = fmt.Sprintf("http://%s/User", config.ServerConfigInstance.Address)
+	AgentUrlPrefix = fmt.Sprintf("http://%s/Agent", config.ServerConfigInstance.Address)
+)
 
 const (
 	GET    = "GET"
@@ -22,23 +22,18 @@ const (
 )
 
 func sendProtobufRequest[T, S proto.Message](url string, methodType string, req T, res S) error {
-
-	// 序列化 Protobuf 消息
+	var err error
 	data, err := proto.Marshal(req)
 	if err != nil {
 		return fmt.Errorf("failed to marshal request: %w", err)
 	}
 
-	// 创建 HTTP 请求
 	httpReq, err := http.NewRequest(methodType, url, bytes.NewReader(data))
 	if err != nil {
 		return fmt.Errorf("failed to create request: %w", err)
 	}
-
-	// 设置请求头
 	httpReq.Header.Set("Content-Type", "application/x-protobuf")
 
-	// 发送请求
 	client := &http.Client{}
 	resp, err := client.Do(httpReq)
 	if err != nil {
@@ -46,30 +41,13 @@ func sendProtobufRequest[T, S proto.Message](url string, methodType string, req
 	}
 	defer resp.Body.Close()
 
-	// 读取响应
 	body, err := io.ReadAll(resp.Body)
 	if err != nil {
 		return fmt.Errorf("failed to read response body: %w", err)
 	}
 
-	if err := proto.Unmarshal(body, res); err != nil {
+	if err = proto.Unmarshal(body, res); err != nil {
 		return fmt.Errorf("failed to unmarshal response: %w", err)
 	}
-	fmt.Println(res)
 	return nil
 }
-
-func TestListAgents(t *testing.T) {
-	url := fmt.Sprintf("%s/ApplyPipelineConfigToAgentGroup", UserUrlPrefix)
-
-	req := &protov2.ApplyConfigToAgentGroupRequest{}
-	res := &protov2.ApplyConfigToAgentGroupResponse{}
-
-	req.RequestId = []byte("123456")
-	req.GroupName = "nzh"
-	req.ConfigName = "nzh"
-
-	if err := sendProtobufRequest(url, PUT, req, res); err != nil {
-		log.Fatalf("Request failed: %v", err)
-	}
-}
diff --git a/config_server/v2/service/test/request/instance_config.go b/config_server/v2/service/test/request/instance_config.go
new file mode 100644
index 0000000000..725b8fc210
--- /dev/null
+++ b/config_server/v2/service/test/request/instance_config.go
@@ -0,0 +1 @@
+package request
diff --git a/config_server/v2/service/test/request/pipeline_config.go b/config_server/v2/service/test/request/pipeline_config.go
new file mode 100644
index 0000000000..332668691a
--- /dev/null
+++ b/config_server/v2/service/test/request/pipeline_config.go
@@ -0,0 +1,119 @@
+package request
+
+import (
+	"config-server/protov2"
+	"fmt"
+)
+
+func CreatePipelineConfig(requestId []byte, detail *protov2.ConfigDetail) (*protov2.CreateConfigResponse, error) {
+	url := fmt.Sprintf("%s/CreatePipelineConfig", UserUrlPrefix)
+	req := &protov2.CreateConfigRequest{}
+	res := &protov2.CreateConfigResponse{}
+	req.RequestId = requestId
+	req.ConfigDetail = detail
+
+	err := sendProtobufRequest(url, POST, req, res)
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
+
+func GetPipelineConfig(requestId []byte, name string) (*protov2.GetConfigResponse, error) {
+	url := fmt.Sprintf("%s/GetPipelineConfig", UserUrlPrefix)
+	req := &protov2.GetConfigRequest{}
+	res := &protov2.GetConfigResponse{}
+	req.RequestId = requestId
+	req.ConfigName = name
+
+	err := sendProtobufRequest(url, POST, req, res)
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
+
+func GetAllPipelineConfig(requestId []byte) (*protov2.ListConfigsResponse, error) {
+	url := fmt.Sprintf("%s/ListPipelineConfigs", UserUrlPrefix)
+	req := &protov2.ListConfigsRequest{}
+	res := &protov2.ListConfigsResponse{}
+	req.RequestId = requestId
+
+	err := sendProtobufRequest(url, POST, req, res)
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
+
+func UpdatePipelineConfig(requestId []byte, detail *protov2.ConfigDetail) (*protov2.UpdateConfigResponse, error) {
+	url := fmt.Sprintf("%s/UpdatePipelineConfig", UserUrlPrefix)
+	req := &protov2.UpdateConfigRequest{}
+	res := &protov2.UpdateConfigResponse{}
+	req.RequestId = requestId
+	req.ConfigDetail = detail
+
+	err := sendProtobufRequest(url, POST, req, res)
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
+
+func DeletePipelineConfig(requestId []byte, name string) (*protov2.DeleteConfigResponse, error) {
+	url := fmt.Sprintf("%s/DeletePipelineConfig", UserUrlPrefix)
+	req := &protov2.DeleteConfigRequest{}
+	res := &protov2.DeleteConfigResponse{}
+	req.RequestId = requestId
+	req.ConfigName = name
+
+	err := sendProtobufRequest(url, POST, req, res)
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
+
+func ApplyPipelineConfig2AgentGroup(requestId []byte, configName string, agentGroupName string) (*protov2.ApplyConfigToAgentGroupResponse, error) {
+	url := fmt.Sprintf("%s/ApplyPipelineConfigToAgentGroup", UserUrlPrefix)
+	req := &protov2.ApplyConfigToAgentGroupRequest{}
+	res := &protov2.ApplyConfigToAgentGroupResponse{}
+	req.RequestId = requestId
+	req.ConfigName = configName
+	req.GroupName = agentGroupName
+
+	err := sendProtobufRequest(url, POST, req, res)
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
+
+func RemovePipelineConfigFromAgentGroup(requestId []byte, configName string, groupName string) (*protov2.RemoveConfigFromAgentGroupResponse, error) {
+	url := fmt.Sprintf("%s/RemovePipelineConfigFromAgentGroup", UserUrlPrefix)
+	req := &protov2.RemoveConfigFromAgentGroupRequest{}
+	res := &protov2.RemoveConfigFromAgentGroupResponse{}
+	req.RequestId = requestId
+	req.ConfigName = configName
+	req.GroupName = groupName
+
+	err := sendProtobufRequest(url, POST, req, res)
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
+
+func GetAppliedAgentGroupForPipelineConfig(requestId []byte, configName string) (*protov2.GetAppliedAgentGroupsResponse, error) {
+	url := fmt.Sprintf("%s/GetAppliedAgentGroupsWithPipelineConfig", UserUrlPrefix)
+	req := &protov2.GetAppliedAgentGroupsRequest{}
+	res := &protov2.GetAppliedAgentGroupsResponse{}
+	req.RequestId = requestId
+	req.ConfigName = configName
+
+	err := sendProtobufRequest(url, POST, req, res)
+	if err != nil {
+		return nil, err
+	}
+	return res, nil
+}
diff --git a/config_server/v2/service/test/store_test.go b/config_server/v2/service/test/store_test.go
new file mode 100644
index 0000000000..56e5404079
--- /dev/null
+++ b/config_server/v2/service/test/store_test.go
@@ -0,0 +1 @@
+package test
diff --git a/config_server/service/utils/environment.go b/config_server/v2/service/utils/environment.go
similarity index 100%
rename from config_server/service/utils/environment.go
rename to config_server/v2/service/utils/environment.go
diff --git a/config_server/service/utils/json.go b/config_server/v2/service/utils/json.go
similarity index 100%
rename from config_server/service/utils/json.go
rename to config_server/v2/service/utils/json.go
diff --git a/config_server/service/utils/list.go b/config_server/v2/service/utils/list.go
similarity index 100%
rename from config_server/service/utils/list.go
rename to config_server/v2/service/utils/list.go
diff --git a/config_server/service/utils/str.go b/config_server/v2/service/utils/str.go
similarity index 100%
rename from config_server/service/utils/str.go
rename to config_server/v2/service/utils/str.go
diff --git a/config_server/service/utils/task.go b/config_server/v2/service/utils/task.go
similarity index 100%
rename from config_server/service/utils/task.go
rename to config_server/v2/service/utils/task.go

From 5893c25b6f35fcc07fe3ce5027b01b6afa87993d Mon Sep 17 00:00:00 2001
From: ww67652 <1749113286@qq.com>
Date: Wed, 30 Oct 2024 20:10:01 +0800
Subject: [PATCH 09/11] feat: refactor directory and sync agent.pb

---
 config_server/{v1 => }/protocol/README.md     |   0
 .../{v1 => }/protocol/v1/agent.proto          |   0
 config_server/{v1 => }/protocol/v1/user.proto |   0
 config_server/{v2 => }/protocol/v2/README.md  |   0
 .../{v1 => }/protocol/v2/agentV2.proto        |   0
 config_server/{v2 => }/protocol/v2/user.proto |   2 +-
 config_server/v1/protocol/v2/README.md        | 251 ------------------
 config_server/v2/deployment/.env              |   5 +
 config_server/v2/deployment/Dockerfile-Agent  |  18 ++
 config_server/v2/deployment/README.md         |  38 +++
 .../v2/deployment/docker-compose.yml          |  54 ++++
 .../deployment/ilogtail_config.template.json  |   8 +
 config_server/v2/protocol/README.md           |   7 -
 config_server/v2/protocol/v1/agent.proto      | 134 ----------
 config_server/v2/protocol/v1/user.proto       | 234 ----------------
 config_server/v2/protocol/v2/agent.proto      | 168 ------------
 config_server/v2/service/README.md            |   2 -
 config_server/v2/service/config/server.go     |   2 +-
 config_server/v2/service/protov2/README.md    |   2 +-
 config_server/v2/service/protov2/agent.pb.go  | 181 +++++++------
 config_server/v2/service/router/router.go     |  12 -
 config_server/v2/service/utils/environment.go |   2 +-
 22 files changed, 217 insertions(+), 903 deletions(-)
 rename config_server/{v1 => }/protocol/README.md (100%)
 rename config_server/{v1 => }/protocol/v1/agent.proto (100%)
 rename config_server/{v1 => }/protocol/v1/user.proto (100%)
 rename config_server/{v2 => }/protocol/v2/README.md (100%)
 rename config_server/{v1 => }/protocol/v2/agentV2.proto (100%)
 rename config_server/{v2 => }/protocol/v2/user.proto (99%)
 delete mode 100644 config_server/v1/protocol/v2/README.md
 create mode 100644 config_server/v2/deployment/.env
 create mode 100755 config_server/v2/deployment/Dockerfile-Agent
 create mode 100644 config_server/v2/deployment/README.md
 create mode 100644 config_server/v2/deployment/docker-compose.yml
 create mode 100644 config_server/v2/deployment/ilogtail_config.template.json
 delete mode 100644 config_server/v2/protocol/README.md
 delete mode 100644 config_server/v2/protocol/v1/agent.proto
 delete mode 100644 config_server/v2/protocol/v1/user.proto
 delete mode 100644 config_server/v2/protocol/v2/agent.proto

diff --git a/config_server/v1/protocol/README.md b/config_server/protocol/README.md
similarity index 100%
rename from config_server/v1/protocol/README.md
rename to config_server/protocol/README.md
diff --git a/config_server/v1/protocol/v1/agent.proto b/config_server/protocol/v1/agent.proto
similarity index 100%
rename from config_server/v1/protocol/v1/agent.proto
rename to config_server/protocol/v1/agent.proto
diff --git a/config_server/v1/protocol/v1/user.proto b/config_server/protocol/v1/user.proto
similarity index 100%
rename from config_server/v1/protocol/v1/user.proto
rename to config_server/protocol/v1/user.proto
diff --git a/config_server/v2/protocol/v2/README.md b/config_server/protocol/v2/README.md
similarity index 100%
rename from config_server/v2/protocol/v2/README.md
rename to config_server/protocol/v2/README.md
diff --git a/config_server/v1/protocol/v2/agentV2.proto b/config_server/protocol/v2/agentV2.proto
similarity index 100%
rename from config_server/v1/protocol/v2/agentV2.proto
rename to config_server/protocol/v2/agentV2.proto
diff --git a/config_server/v2/protocol/v2/user.proto b/config_server/protocol/v2/user.proto
similarity index 99%
rename from config_server/v2/protocol/v2/user.proto
rename to config_server/protocol/v2/user.proto
index 5fe277fe43..7c6b37f3c0 100644
--- a/config_server/v2/protocol/v2/user.proto
+++ b/config_server/protocol/v2/user.proto
@@ -1,6 +1,6 @@
 syntax = "proto3";
 option go_package = "/protov2;";
-import "agent.proto";
+import "agentV2.proto";
 
 
 message Agent{
diff --git a/config_server/v1/protocol/v2/README.md b/config_server/v1/protocol/v2/README.md
deleted file mode 100644
index 129cc14f40..0000000000
--- a/config_server/v1/protocol/v2/README.md
+++ /dev/null
@@ -1,251 +0,0 @@
-# 统一管控协议
-
-本规范定义了 Agent 管控网络协议以及 iLogtail 和 ConfigServer 的预期行为。
-
-1. 只要XxxConfigServer实现了协议,那么就可以管控Agent做Yyy事情。
-2. 只要Agent实现了协议,那么任何XxxConfigServer就能过管控该Agent做Yyy事情。
-
-## 管控协议
-
-/Agent/Heartbeat?InstanceId=$instance\_id&WaitForChange=(true|false)
-
-### HeartbeatRequest 消息
-
-    message HeartbeatRequest {
-        bytes request_id = 1;
-        uint64 sequence_num = 2;                    // Increment every request, for server to check sync status
-        uint64 capabilities = 3;                    // Bitmask of flags defined by AgentCapabilities enum
-        bytes instance_id = 4;                      // Required, Agent's unique identification, consistent throughout the process lifecycle
-        string agent_type = 5;                      // Required, Agent's type(ilogtail, ..)
-        AgentAttributes attributes = 6;             // Agent's basic attributes
-        repeated AgentGroupTag tags =  7;           // Agent's tags
-        string running_status = 8;                  // Human readable running status
-        int64 startup_time = 9;                     // Required, Agent's startup time
-        repeated ConfigInfo pipeline_configs = 10;  // Information about the current PIPELINE_CONFIG held by the Agent
-        repeated ConfigInfo instance_configs = 11;   // Information about the current AGENT_CONFIG held by the Agent
-        repeated CommandInfo custom_commands = 12;  // Information about command history
-        uint64 flags = 13;                          // Predefined command flag
-        bytes opaque = 14;                          // Opaque data for extension
-        // before 100 (inclusive) are reserved for future official fields
-    }
-    
-    message AgentGroupTag {
-        string name = 1;
-        string value = 2;
-    }
-
-    enum ConfigStatus {
-        // The value of status field is not set.
-        UNSET = 0;
-        // Agent is currently applying the remote config that it received earlier.
-        APPLYING = 1;
-        // Remote config was successfully applied by the Agent.
-        APPLIED = 2;
-        // Agent tried to apply the config received earlier, but it failed.
-        // See error_message for more details.
-        FAILED = 3;
-    }
-
-    // Define the Config information carried in the request
-    message ConfigInfo {
-        string name = 1;         // Required, Config's unique identification
-        int64 version = 2;       // Required, Config's version number or hash code
-        ConfigStatus status = 3; // Config's status
-    }
-
-    // Define the Command information carried in the request
-    message CommandInfo {
-        string type = 1;         // Command's type
-        string name = 2;         // Required, Command's unique identification
-        ConfigStatus status = 3; // Command's status
-    }
-
-    // Define Agent's basic attributes
-    message AgentAttributes {
-        bytes version = 1;                 // Agent's version
-        bytes ip = 2;                      // Agent's ip
-        bytes hostname = 3;                // Agent's hostname
-        map<string, bytes> extras = 100;   // Agent's other attributes
-        // before 100 (inclusive) are reserved for future official fields
-    }
-
-    enum AgentCapabilities {
-        // The capabilities field is unspecified.
-        UnspecifiedAgentCapability = 0;
-        // The Agent can accept pipeline configuration from the Server.
-        AcceptsPipelineConfig          = 0x00000001;
-        // The Agent can accept instance configuration from the Server.
-        AcceptsInstanceConfig           = 0x00000002;
-        // The Agent can accept custom command from the Server.
-        AcceptsCustomCommand           = 0x00000004;
-
-        // bits before 2^16 (inclusive) are reserved for future official fields
-    }
-
-    enum RequestFlags {
-        RequestFlagsUnspecified = 0;
-
-        // Flags is a bit mask. Values below define individual bits.
-
-        // Must be set if this request contains full state
-        FullState               = 0x00000001;
-        // bits before 2^16 (inclusive) are reserved for future official fields
-    }
-
-### HeartbeatResponse 消息
-
-    message HeartbeatResponse {
-        bytes request_id = 1;  
-        ServerErrorResponse error_response = 2;             // Set value indicates error
-        uint64 capabilities = 3;                            // Bitmask of flags defined by ServerCapabilities enum
-
-        repeated ConfigDetail pipeline_config_updates = 4;  // Agent's pipeline config update status
-        repeated ConfigDetail instance_config_updates = 5;   // Agent's instance config update status
-        repeated CommandDetail custom_command_updates = 6;  // Agent's commands updates
-        uint64 flags = 7;                                   // Predefined command flag
-        bytes opaque = 8;                                   // Opaque data for extension
-    }
-    
-    message ConfigDetail {
-        string name = 1;        // Required, Config's unique identification
-        int64 version = 2;      // Required, Config's version number or hash code
-        bytes detail = 3;       // Required, Config's detail
-    }
-
-    message CommandDetail {
-        string type = 1;                // Required, Command type
-        string name = 2;                // Required, Command name
-        bytes detail = 3;               // Required, Command's detail
-        int64 expire_time = 4;          // After which the command can be safely removed from history
-    }
-
-    enum ServerCapabilities {
-        // The capabilities field is unspecified.
-        UnspecifiedServerCapability = 0;
-        // The Server can remember agent attributes.
-        RembersAttribute                   = 0x00000001;
-        // The Server can remember pipeline config status.
-        RembersPipelineConfigStatus        = 0x00000002;
-        // The Server can remember instance config status.
-        RembersInstanceConfigStatus         = 0x00000004;
-        // The Server can remember custom command status.
-        RembersCustomCommandStatus         = 0x00000008;
-
-        // bits before 2^16 (inclusive) are reserved for future official fields
-    }
-
-    message ServerErrorResponse {
-        int32 error_code = 1;                               // None-zero value indicates error
-        string error_message = 2;                           // Error message
-    }
-
-    enum ResponseFlags {
-        ResponseFlagsUnspecified = 0;
-
-        // Flags is a bit mask. Values below define individual bits.
-
-        // ReportFullState flag can be used by the Server if the Client did not include
-        // some sub-message in the last AgentToServer message (which is an allowed
-        // optimization) but the Server detects that it does not have it (e.g. was
-        // restarted and lost state).
-        ReportFullState           = 0x00000001;
-        FetchPipelineConfigDetail = 0x00000002;
-        FetchInstanceConfigDetail  = 0x00000004;
-        // bits before 2^16 (inclusive) are reserved for future official fields
-    }
-
-## 行为规范
-
-对于管控协议来说 iLogtail 的预期行为是确定性的,对于实现本管控协议的其他 Agent 其具体行为可自行确定,但语义应保持一致。Server 端定义了可选的行为的不同实现,此时对于这些差异 Agent 侧在实现时必须都考虑到且做好兼容。这样,Agent只需要实现一个CommonConfigProvider就可以受任意符合此协议规范的ConfigServer管控。
-
-### 能力报告
-
-Client:应当通过capbilitiies上报Agent自身的能力,这样如果老的客户端接入新的ConfigServer,ConfigServer便知道客户端不具备某项能力,从而不会向其发送不支持的配置或命令而得不到状态汇报导致无限循环。
-
-Server:应当通过capbilitiies上报Server自身的能力,这样如果新的客户端接入老的ConfigServer,Agent便知道服务端不具备某项能力,从而不会被其响应所误导,如其不具备记忆Attributes能力,那么Attributes字段无论如何都不应该在心跳中被省略。
-
-### 注册
-
-Client:Agent启动后第一次向Server汇报全量信息,request字段应填尽填。request\_id、sequence\_num、capabilities、instance\_id、agent\_type、startup\_time为必填字段。
-
-Server:Server根据上报的信息返回响应。pipeline\_config\_updates、instance\_config\_updates中包含agent需要同步的配置,updates中必然包含name和version,是否包含详情context和detail取决于server端实现。custom\_command_updates包含要求agent执行的命令command中必然包含type、name和expire\_time。
-
-Server是否保存Client信息取决于Server实现,如果服务端找不到或保存的sequence\_num + 1 ≠ 心跳的sequence\_num,那么就立刻返回并且flags中必须设置ReportFullStatus标识位。
-
-Server根据agent\_type + attributes 查询进程配置,根据ip和tags查询机器组和关联采集配置。
-
-![image](https://github.com/alibaba/ilogtail/assets/1827594/05799ac2-9249-49ed-8088-3b927821ac73)
-
-### 心跳(心跳压缩)
-
-Client:若接收到的响应中没有ReportFullStatus,且client的属性、配置状态、命令状态在上次上报后没有变化,那么可以只填instance\_id、sequence\_num,sequence\_num每次请求+1。若有ReportStatus或任何属性、配置状态变化或Server不支持属性、配置状态记忆能力,则必须完整上报状态。
-
-Server:同注册
-
-允许心跳压缩
-
-![image](https://github.com/alibaba/ilogtail/assets/1827594/ad22bcfa-b14a-41b5-b4b8-4956bb065bf7)
-
-不允许心跳压缩
-
-![image](https://github.com/alibaba/ilogtail/assets/1827594/35a823fd-6b8e-499f-951e-2231f3319420)
-
-### 进程配置
-
-若Server的注册/心跳响应中有instance\_config\_updates.detail
-
-Client:直接从response中获得detail,应用成功后下次心跳需要上报完整状态。
-
-若Server的响应不包含detail
-
-Client:根据instance\_config\_updates的信息构造FetchInstanceConfigRequest
-
-Server:返回FetchInstanceConfigResponse
-
-Client获取到多个进程配置时,自动合并,若产生冲突默认行为是未定义。
-
-### 采集配置
-
-若Server的注册/心跳响应中有pipeline\_config\_updates.detail
-
-Client:直接从response中获得detail,应用成功后下次心跳需要上报完整状态。
-
-若Server的响应不包含detail
-
-Client:根据pipeline\_config\_updates的信息构造FetchPipelineConfigRequest
-
-Server:返回FetchPipelineConfigResponse
-
-客户端支持以下2种实现
-
-实现1:直接将Detail返回在心跳响应中(FetchConfigDetail flag is unset)
-
-![image](https://github.com/alibaba/ilogtail/assets/1827594/be645615-dd99-42dd-9deb-681e9a4069bb)
-
-实现2:仅返回配置名和版本,Detail使用单独请求获取(FetchConfigDetail flag is set)
-
-![image](https://github.com/alibaba/ilogtail/assets/1827594/c409c35c-2a81-4927-bfd2-7fb321ef1ca8)
-
-### 配置状态上报
-
-Client:这个版本的配置状态上报中修改了version的定义,-1仍然表示删除,0作为保留值,其他值都是合法version,只要version不同Client都应该视为配置更新。此外参考OpAMP增加了配置应用状态上报的字段,能反应出下发的配置是否生效。
-
-Server:这些信息是Agent状态的一部分,可选保存。与通过Event上报可观测信息不同的是,作为状态信息没有时间属性,用户可通过接口可获取即刻状态,而不需要选择时间窗口合并事件。
-
-### 预定义命令
-
-Client: 通过request的flag传递,定义了FullStatus,表明本条信息为全量状态
-
-Server: 通过response的flag传递,定义了ReportFullStatus,表明要求Client上报全量状态信息
-
-### 自定义命令
-
-Client: 为了防止服务端重复下发命令以及感知命令执行结果,在command expire前,Client始终应具备向服务端上报command执行状态的能力,实际是否上报取决于心跳压缩机制。在expire\_time超过后,client不应该再上报超时的command状态。
-
-Server: 如果上报+已知的Agent状态中,缺少应下发的custom\_command\_updates(通过name识别),那么server应该在响应中下发缺少的custom\_command\_updates。
-
-### 异常处理
-
-Server: 服务端正常返回时HeartbeatResponse中的code应始终设置为0,而当服务端异常时,必须将HeartbeatResponse中的code设置为非0,HeartbeatResponse中的message应包含错误信息,此时Response中的其他字段必须为空。
-
-Client: 当HeartbeatResponse中的code为0时,Agent应该正常处理下发的配置。当HeartbeatResponse中的code不为0时,Agent必须忽略除code和message外的其他字段,并择机重试。
diff --git a/config_server/v2/deployment/.env b/config_server/v2/deployment/.env
new file mode 100644
index 0000000000..d99ed73a9e
--- /dev/null
+++ b/config_server/v2/deployment/.env
@@ -0,0 +1,5 @@
+CONFIG_SERVER=../service
+CONFIG_SERVER_UI=../ui
+
+# 需把该目录下的Dockerfile-agent复制到agent对应的目录下,并修改${AGENT}为agent所在目录路径
+AGENT=/home/source-code
\ No newline at end of file
diff --git a/config_server/v2/deployment/Dockerfile-Agent b/config_server/v2/deployment/Dockerfile-Agent
new file mode 100755
index 0000000000..b04424d8f8
--- /dev/null
+++ b/config_server/v2/deployment/Dockerfile-Agent
@@ -0,0 +1,18 @@
+FROM centos:7
+
+RUN curl -L -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo \
+    && yum update -y \
+    && yum upgrade -y \
+    && yum -y clean all \
+    && rm -fr /var/cache \
+    && rm -rf /core.* \
+    && yum install -y gettext
+
+WORKDIR /agent
+COPY . .
+
+CMD envsubst < ilogtail_config.template.json > ilogtail_config.json \
+    && sh -c ./ilogtail > stdout.log 2> stderr.log
+
+
+
diff --git a/config_server/v2/deployment/README.md b/config_server/v2/deployment/README.md
new file mode 100644
index 0000000000..b9fdb62857
--- /dev/null
+++ b/config_server/v2/deployment/README.md
@@ -0,0 +1,38 @@
+# 部署说明
+
+本项目实现了config-server的后端(config-server)与前端(config-server-ui),并基于docker与docker-compose的方式进行部署
+
+## 快速开始
+
+进入`deployment`目录,运行`deployment-compose.yml`,启动三个容器(`mysql`、`config-server`、`config-server-ui`)
+
+```shell
+docker compose -f docker-compose.yml up -d
+```
+
+启动成功后,通过`http://{your-ip}:8080`即可实现前端页面的访问
+
+## Agent启动
+
+由于最新版本的[ilogtail](https://github.com/alibaba/ilogtail/releases/tag/v2.0.7)(截止到2.0.7)尚未提供支持v2心跳的功能,为了便于使用(测试)`config-server-ui`,本项目提供了基于docker启动Agent的脚本,复制`Dockefile-Agent`与`ilogtail_config.template.json`到Agent的目录下,
+修改`.env`中的`${AGENT}`为Agent所在目录路径(Agent安装与启动见[quick-start](https://github.com/alibaba/ilogtail/blob/main/docs/cn/installation/quick-start.md)),并在`docker-compose.yml`添加
+```yml
+  agent:
+    build:
+      context: ${AGENT}
+      dockerfile: Dockerfile-Agent
+    image: ilogtail:openSource
+    environment:
+      CONFIG_SERVER_ADDRESSES: '["config-server:9090"]'
+      TZ: Asia/Shanghai
+    deploy:
+      replicas: 3
+    networks:
+      - server
+```
+
+再次运行下面的命令,这将会启动3个ilogtail Agent。
+
+```shell
+docker compose -f docker-compose.yml up -d
+```
\ No newline at end of file
diff --git a/config_server/v2/deployment/docker-compose.yml b/config_server/v2/deployment/docker-compose.yml
new file mode 100644
index 0000000000..7a6c893fb3
--- /dev/null
+++ b/config_server/v2/deployment/docker-compose.yml
@@ -0,0 +1,54 @@
+version: '3.8'
+services:
+  mysql:
+    image: mysql:latest
+    volumes:
+      - /var/lib/mysql:/var/lib/mysql
+    ports:
+      - "3306:3306"
+    environment:
+      MYSQL_ROOT_PASSWORD: "123456"
+    cap_add:
+      - SYS_NICE
+    healthcheck:
+      test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ]
+      interval: 10s
+      retries: 5
+      timeout: 5s
+    networks:
+      - server
+
+  config-server:
+    build:
+      context: ${CONFIG_SERVER}
+      dockerfile: Dockerfile
+    # 如果之前构建过镜像,再次docker compose则不会重新构建
+    image: config-server:openSource
+    ports:
+      - "9090:9090"
+    environment:
+      TZ: Asia/Shanghai
+    extra_hosts:
+      - "host.docker.internal:host-gateway"
+    networks:
+      - server
+    depends_on:
+      mysql:
+        condition: service_healthy
+
+  config-server-ui:
+    build:
+      context: ${CONFIG_SERVER_UI}
+      dockerfile: Dockerfile
+    image: config-server-ui:openSource
+    ports:
+      - "8080:8080"
+    environment:
+      TZ: Asia/Shanghai
+    extra_hosts:
+      - "host.docker.internal:host-gateway"
+    networks:
+      - server
+#替换成你自己的网络
+networks:
+  server:
diff --git a/config_server/v2/deployment/ilogtail_config.template.json b/config_server/v2/deployment/ilogtail_config.template.json
new file mode 100644
index 0000000000..eaf828bb58
--- /dev/null
+++ b/config_server/v2/deployment/ilogtail_config.template.json
@@ -0,0 +1,8 @@
+{
+  "config_server_list" : [
+    {
+      "cluster":"community",
+      "endpoint_list":$CONFIG_SERVER_ADDRESSES
+    }
+  ]
+}
\ No newline at end of file
diff --git a/config_server/v2/protocol/README.md b/config_server/v2/protocol/README.md
deleted file mode 100644
index 783fb68970..0000000000
--- a/config_server/v2/protocol/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# 管控协议说明
-
-ConfigServer管控协议的总贴、V1版本协议说明和翻新至V2的讨论参见
-[服务端管控协议共建,欢迎参与讨论交流](https://github.com/alibaba/ilogtail/discussions/404)。
-
-V2版本的讨论参见
-[心跳&配置同步流程重构讨论](https://github.com/alibaba/ilogtail/discussions/1491#discussioncomment-9547735)。
diff --git a/config_server/v2/protocol/v1/agent.proto b/config_server/v2/protocol/v1/agent.proto
deleted file mode 100644
index fe56d24f0d..0000000000
--- a/config_server/v2/protocol/v1/agent.proto
+++ /dev/null
@@ -1,134 +0,0 @@
-syntax = "proto3";
-package configserver.proto;
-option go_package = ".;configserver_proto";
-
-// Define Config's type
-enum ConfigType {
-    PIPELINE_CONFIG = 0; 
-    AGENT_CONFIG = 1;      
-}
-
-// Define Config's update status
-enum CheckStatus {
-    NEW = 0;
-    DELETED = 1;
-    MODIFIED = 2;
-}
-
-// Define response code
-enum RespCode {
-    ACCEPT = 0;                 
-    INVALID_PARAMETER = 1;      
-    INTERNAL_SERVER_ERROR = 2;  
-}
-
-// Define the Config information carried in the request
-message ConfigInfo {
-    ConfigType type = 1;    // Required, Config's type
-    string name = 2;        // Required, Config's unique identification
-    int64 version = 3;      // Required, Config's version number
-    string context = 4;     // Config's context
-}
-
-// Define the result of checking the Config update status
-message ConfigCheckResult {
-    ConfigType type = 1;            // Required, Config's type
-    string name = 2;                // Required, Config's unique identification
-    int64 old_version = 3;          // Required, Config's current version number
-    int64 new_version = 4;          // Required, Config's latest version number
-    string context = 5;             // Config's context
-    CheckStatus check_status = 6;   // Required, Config's update status   
-}
-
-// Define Config's detail
-message ConfigDetail {
-    ConfigType type = 1;    // Required, Config's type
-    string name = 2;        // Required, Config's unique identification
-    int64 version = 3;      // Required, Config's version number
-    string context = 4;     // Config's context
-    string detail = 5;      // Required, Config's detail
-}
-
-// Define Agent's basic attributes
-message AgentAttributes {
-    string version = 1;                 // Agent's version
-    string category = 2;                // Agent's type(used to distinguish AGENT_CONFIG)
-    string ip = 3;                      // Agent's ip
-    string hostname = 4;                // Agent's hostname
-    string region = 5;                  // Agent's region
-    string zone = 6;                    // Agent's zone
-    map<string, string> extras = 100;   // Agent's other attributes
-}
-
-// Define command
-message Command {
-    string type = 1;                // Required, Command type
-    string name = 2;                // Required, Command name
-    string id = 3;                  // Required, Command id
-    map<string, string> args = 4;   // Command's parameter arrays
-}
-
-// API: /Agent/HeartBeat/
-
-// Agent sends requests to the ConfigServer to send heartbeats, get config updates and receive commands.
-message HeartBeatRequest {
-    string request_id = 1;  
-
-    string agent_id = 2;                        // Required, Agent's unique identification
-    string agent_type = 3;                      // Required, Agent's type(ilogtail, ..)
-    AgentAttributes attributes = 4;             // Agent's basic attributes
-    repeated string tags =  5;                  // Agent's tags
-    string running_status = 6;                  // Required, Agent's running status
-    int64 startup_time = 7;                     // Required, Agent's startup time
-    int32 interval = 8;                         // Agent's heartbeat interval
-    repeated ConfigInfo pipeline_configs = 9;   // Information about the current PIPELINE_CONFIG held by the Agent
-    repeated ConfigInfo agent_configs = 10;     // Information about the current AGENT_CONFIG held by the Agent
-}
-
-// ConfigServer's response to Agent's heartbeats
-message HeartBeatResponse {
-    string request_id = 1;  
-    RespCode code = 2;      
-    string message = 3;     
-
-    repeated ConfigCheckResult pipeline_check_results = 4;  // Agent's PIPELINE_CONFIG update status
-    repeated ConfigCheckResult agent_check_results = 5;     // Agent's AGENT_CONFIG update status
-    repeated Command custom_commands = 6;                   // Agent received commands
-}
-
-// API: /Agent/FetchPipelineConfig/
-// Agent request to ConfigServer, pulling details of the PIPELINE_CONFIG
-message FetchPipelineConfigRequest {
-    string request_id = 1; 
-
-    string agent_id = 2;                    // Required, Agent's unique identification
-    repeated ConfigInfo req_configs = 3;    // PIPELINE_CONFIGs that Agent requires for full information
-}
-
-// ConfigServer response to Agent's request
-message FetchPipelineConfigResponse {
-    string request_id = 1;                     
-    RespCode code = 2;      
-    string message = 3;     
-
-    repeated ConfigDetail config_details = 4;   // PIPELINE_CONFIGs' detail
-}
-
-// API: /Agent/FetchAgentConfig/
-// Agent request to ConfigServer, pulling details of the AGENT_CONFIG
-message FetchAgentConfigRequest {
-    string request_id = 1; 
-
-    string agent_id = 2;                    // Required, Agent's unique identification
-    AgentAttributes attributes = 3;         // Required, Agent's basic attributes
-    repeated ConfigInfo req_configs = 4;    // AGENT_CONFIGs that Agent requires for full information
-}
-
-// ConfigServer response to Agent's request
-message FetchAgentConfigResponse {
-    string request_id = 1;         
-    RespCode code = 2;               
-    string message = 3;                   
-
-    repeated ConfigDetail config_details = 4;   // AGENT_CONFIGs' detail
-}
\ No newline at end of file
diff --git a/config_server/v2/protocol/v1/user.proto b/config_server/v2/protocol/v1/user.proto
deleted file mode 100644
index 4a6147fdc2..0000000000
--- a/config_server/v2/protocol/v1/user.proto
+++ /dev/null
@@ -1,234 +0,0 @@
-syntax = "proto3";
-package configserver.proto;
-option go_package = ".;configserver_proto";
-import "agent.proto";
-
-message AgentGroupTag {
-    string name = 1;
-    string value = 2;
-}
-
-message AgentGroup {
-    string group_name = 1;
-    string description = 2;
-    repeated AgentGroupTag tags = 3;
-}
-
-message Agent {
-    string agent_id = 1;            // Required, Agent's unique identification
-    string agent_type = 2;          // Required, Agent's type(ilogtail, ..)
-    AgentAttributes attributes = 3; // Agent's basic attributes
-    repeated string tags =  4;      // Agent's tags
-    string running_status = 5;      // Required, Agent's running status
-    int64 startup_time = 6;         // Required, Agent's startup time
-    int32 interval = 7;             // Agent's heartbeat interval
-}
-
-// API: /User/CreateAgentGroup
-
-message CreateAgentGroupRequest {
-    string request_id = 1;
-    AgentGroup agent_group = 2;
-}
-
-message CreateAgentGroupResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-}
-
-// API: /User/UpdateAgentGroup
-
-message UpdateAgentGroupRequest {
-    string request_id = 1;
-    AgentGroup agent_group = 2;
-}
-
-message UpdateAgentGroupResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-}
-
-// API: /User/DeleteAgentGroup/
-
-message DeleteAgentGroupRequest {
-    string request_id = 1;
-    string group_name = 2;
-}
-
-message DeleteAgentGroupResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-}
-
-// API: /User/GetAgentGroup/
-
-message GetAgentGroupRequest {
-    string request_id = 1;
-    string group_name = 2;
-}
-
-message GetAgentGroupResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-
-    AgentGroup agent_group = 4;
-}
-
-// API: /User/ListAgentGroups/ 
-
-message ListAgentGroupsRequest {
-    string request_id = 1;
-}
-
-message ListAgentGroupsResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-
-    repeated AgentGroup agent_groups = 4;
-}
-
-// API: /User/CreateConfig/
-
-message CreateConfigRequest {
-    string request_id = 1;
-    ConfigDetail config_detail = 2;
-}
-
-message CreateConfigResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-}
-
-// API: /User/UpdateConfig/
-
-message UpdateConfigRequest {
-    string request_id = 1;
-    ConfigDetail config_detail = 2;
-}
-
-message UpdateConfigResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-}
-
-// API: /User/DeleteConfig/
-
-message DeleteConfigRequest {
-    string request_id = 1;
-    string config_name = 2;
-}
-
-message DeleteConfigResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-}
-
-// API: User/GetConfig/
-
-message GetConfigRequest {
-    string request_id = 1;
-    string config_name = 2;
-}
-
-message GetConfigResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-
-    ConfigDetail config_detail = 4;
-}
-
-// API: /User/ListConfigs/
-
-message ListConfigsRequest {
-    string request_id = 1;
-}
-
-message ListConfigsResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-
-    repeated ConfigDetail config_details = 4;
-}
-
-// API: /User/ApplyConfigToAgentGroup/
-
-message ApplyConfigToAgentGroupRequest {
-    string request_id = 1;
-    string config_name = 2;
-    string group_name = 3;
-}
-
-message ApplyConfigToAgentGroupResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-}
-
-// API: /User/RemoveConfigFromAgentGroup/
-
-message RemoveConfigFromAgentGroupRequest {
-    string request_id = 1;
-    string config_name = 2;
-    string group_name = 3;
-}
-
-message RemoveConfigFromAgentGroupResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-}
-
-// API: /User/GetAppliedConfigsForAgentGroup/
-
-message GetAppliedConfigsForAgentGroupRequest {
-    string request_id = 1;
-    string group_name = 2;
-}
-
-message GetAppliedConfigsForAgentGroupResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-
-    repeated string config_names = 4;
-}
-
-// API: /User/GetAppliedAgentGroups/
-
-message GetAppliedAgentGroupsRequest {
-    string request_id = 1;
-    string config_name = 2;
-}
-
-message GetAppliedAgentGroupsResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-
-    repeated string agent_group_names = 4;
-}
-
-// API: /User/ListAgents/
-
-message ListAgentsRequest {
-    string request_id = 1;
-    string group_name = 2;
-}
-
-message ListAgentsResponse {
-    string response_id = 1;
-    RespCode code = 2;
-    string message = 3;
-
-    repeated Agent agents = 4;
-}
\ No newline at end of file
diff --git a/config_server/v2/protocol/v2/agent.proto b/config_server/v2/protocol/v2/agent.proto
deleted file mode 100644
index d9e52a883f..0000000000
--- a/config_server/v2/protocol/v2/agent.proto
+++ /dev/null
@@ -1,168 +0,0 @@
-syntax = "proto3";
-option go_package = "/protov2;";
-
-message AgentGroupTag {
-    string name = 1;
-    string value = 2;
-}
-
-enum ConfigStatus {
-    // The value of status field is not set.
-    UNSET = 0;
-    // Agent is currently applying the remote config that it received earlier.
-    APPLYING = 1;
-    // Remote config was successfully applied by the Agent.
-    APPLIED = 2;
-    // Agent tried to apply the config received earlier, but it failed.
-    // See error_message for more details.
-    FAILED = 3;
-}
-
-// Define the Config information carried in the request
-message ConfigInfo {
-    string name = 1;         // Required, Config's unique identification
-    int64 version = 2;       // Required, Config's version number or hash code
-    ConfigStatus status = 3; // Config's status
-    string message = 4;      // Optional error message
-}
-
-// Define the Command information carried in the request
-message CommandInfo {
-    string type = 1;         // Command's type
-    string name = 2;         // Required, Command's unique identification
-    ConfigStatus status = 3; // Command's status
-    string message = 4;      // Optional error message
-}
-
-// Define Agent's basic attributes
-message AgentAttributes {
-    bytes version = 1;                 // Agent's version
-    bytes ip = 2;                      // Agent's ip
-    bytes hostname = 3;                // Agent's hostname
-    bytes hostid = 4;                  // Agent's hostid  https://opentelemetry.io/docs/specs/semconv/attributes-registry/host/
-    map<string, bytes> extras = 100;   // Agent's other attributes
-    // before 100 (inclusive) are reserved for future official fields
-}
-
-enum AgentCapabilities {
-    // The capabilities field is unspecified.
-    UnspecifiedAgentCapability = 0;
-    // The Agent can accept pipeline configuration from the Server.
-    AcceptsPipelineConfig          = 0x00000001;
-    // The Agent can accept instance configuration from the Server.
-    AcceptsInstanceConfig           = 0x00000002;
-    // The Agent can accept custom command from the Server.
-    AcceptsCustomCommand           = 0x00000004;
-
-    // Add new capabilities here, continuing with the least significant unused bit.
-}
-
-enum RequestFlags {
-    RequestFlagsUnspecified = 0;
-
-    // Flags is a bit mask. Values below define individual bits.
-
-    // Must be set if this request contains full state
-    FullState               = 0x00000001;
-    // bits before 2^16 (inclusive) are reserved for future official fields
-}
-
-// API: /Agent/Heartbeat
-
-// Agent sends requests to the ConfigServer to get config updates and receive commands.
-message HeartbeatRequest {
-    bytes request_id = 1;
-    uint64 sequence_num = 2;                    // Increment every request, for server to check sync status
-    uint64 capabilities = 3;                    // Bitmask of flags defined by AgentCapabilities enum
-    bytes instance_id = 4;                      // Required, Agent's unique identification, consistent throughout the process lifecycle
-    string agent_type = 5;                      // Required, Agent's type(ilogtail, ..)
-    AgentAttributes attributes = 6;             // Agent's basic attributes
-    repeated AgentGroupTag tags =  7;           // Agent's tags
-    string running_status = 8;                  // Human readable running status
-    int64 startup_time = 9;                     // Required, Agent's startup time
-    repeated ConfigInfo pipeline_configs = 10;  // Information about the current PIPELINE_CONFIG held by the Agent
-    repeated ConfigInfo instance_configs = 11;  // Information about the current AGENT_CONFIG held by the Agent
-    repeated CommandInfo custom_commands = 12;  // Information about command history
-    uint64 flags = 13;                          // Predefined command flag
-    bytes opaque = 14;                          // Opaque data for extension
-    // before 100 (inclusive) are reserved for future official fields
-}
-
-// Define Config's detail
-message ConfigDetail {
-    string name = 1;        // Required, Config's unique identification
-    int64 version = 2;      // Required, Config's version number or hash code
-    bytes detail = 3;       // Required, Config's detail
-}
-
-message CommandDetail {
-    string type = 1;                // Required, Command type
-    string name = 2;                // Required, Command name
-    bytes detail = 3;               // Required, Command's detail
-    int64 expire_time = 4;          // After which the command can be safely removed from history
-}
-
-enum ServerCapabilities {
-    // The capabilities field is unspecified.
-    UnspecifiedServerCapability = 0;
-    // The Server can remember agent attributes.
-    RembersAttribute                   = 0x00000001;
-    // The Server can remember pipeline config status.
-    RembersPipelineConfigStatus        = 0x00000002;
-    // The Server can remember instance config status.
-    RembersInstanceConfigStatus         = 0x00000004;
-    // The Server can remember custom command status.
-    RembersCustomCommandStatus         = 0x00000008;
-
-    // bits before 2^16 (inclusive) are reserved for future official fields
-}
-
-enum ResponseFlags {
-    ResponseFlagsUnspecified = 0;
-
-    // Flags is a bit mask. Values below define individual bits.
-
-    // ReportFullState flag can be used by the Server if the Client did not include
-    // some sub-message in the last AgentToServer message (which is an allowed
-    // optimization) but the Server detects that it does not have it (e.g. was
-    // restarted and lost state).
-    ReportFullState           = 0x00000001;
-    FetchPipelineConfigDetail = 0x00000002;
-    FetchInstanceConfigDetail = 0x00000004;
-    // bits before 2^16 (inclusive) are reserved for future official fields
-}
-
-// ConfigServer's response to Agent's request
-message HeartbeatResponse {
-    bytes request_id = 1;
-    CommonResponse common_response = 2;                  // Set common response
-    uint64 capabilities = 3;                            // Bitmask of flags defined by ServerCapabilities enum
-
-    repeated ConfigDetail pipeline_config_updates = 4;  // Agent's pipeline config update status
-    repeated ConfigDetail instance_config_updates = 5;  // Agent's instance config update status
-    repeated CommandDetail custom_command_updates = 6;  // Agent's commands updates
-    uint64 flags = 7;                                   // Predefined command flag
-    bytes opaque = 8;                                   // Opaque data for extension
-}
-
-// API: /Agent/FetchPipelineConfig/
-// API: /Agent/FetchInstanceConfig/
-// Agent request to ConfigServer, pulling details of the config
-message FetchConfigRequest {
-    bytes request_id = 1;
-    bytes instance_id = 2;                 // Agent's unique identification
-    repeated ConfigInfo req_configs = 3;   // Config's name and version/hash
-}
-
-// ConfigServer response to Agent's request
-message FetchConfigResponse {
-    bytes request_id = 1;
-    CommonResponse common_response = 2;
-    repeated ConfigDetail config_details = 3;   // config detail
-}
-
-message CommonResponse
-{
-    int32 status = 1;
-    bytes error_message = 2;
-}
\ No newline at end of file
diff --git a/config_server/v2/service/README.md b/config_server/v2/service/README.md
index 7538f1578d..504fe134ee 100644
--- a/config_server/v2/service/README.md
+++ b/config_server/v2/service/README.md
@@ -2,8 +2,6 @@
 
 本项目针对https://github.com/alibaba/ilogtail/tree/main/config_server/protocol/v2 中提到的Agent行为进行了V2版本的适配,基本实现了能力报告、心跳压缩、配置状态上报等功能;并适配用户端实现了Config-server的前端页面Config-server-ui,项目见[ui](../ui/README.md)。
 ## 快速开始
-### 基本配置
-下载ilogtail源码,进入`config_server/service`目录
 #### 数据库配置
 
 由于要求ConfigServer存储Agent的基本信息、PipelineConfig、InstanceConfig等配置信息,所以首先需要对数据库进行配置。打开`cmd/config/prod`文件夹,编辑`databaseConfig.json`(若不存在,请先创建),填入以下信息,其中`type`为数据库的基本类型 (基于gorm我们适配了`mysql`、`sqlite`、`postgres`、`sqlserver`四种数据库);其余均为数据库配置信息;`autoMigrate`字段默认为`true`,若先前建好业务相关的表,则设置为`false`。配置完成后,请自行创建可与ConfigServer连通的数据库实例,并创建名字为`dbName`的数据库(若按照docker compose方式启动,无需任何操作,参考[deployment](../deployment/README.md))。
diff --git a/config_server/v2/service/config/server.go b/config_server/v2/service/config/server.go
index 1cfb5d51b0..3579fc59cd 100644
--- a/config_server/v2/service/config/server.go
+++ b/config_server/v2/service/config/server.go
@@ -38,6 +38,6 @@ func GetServerConfiguration() error {
 func init() {
 	err := GetServerConfiguration()
 	if err != nil {
-		return
+		panic(err)
 	}
 }
diff --git a/config_server/v2/service/protov2/README.md b/config_server/v2/service/protov2/README.md
index 7995b9cecc..6b0a26a25e 100644
--- a/config_server/v2/service/protov2/README.md
+++ b/config_server/v2/service/protov2/README.md
@@ -27,7 +27,7 @@ protoc --version
 go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
 ```
 
-进入`protocol/v2`文件夹
+进入`protocol/v2`[文件夹](../../../protocol/v2)
 
 ```shell
 protoc --go_out=. agent.proto
diff --git a/config_server/v2/service/protov2/agent.pb.go b/config_server/v2/service/protov2/agent.pb.go
index 5f7e5e41f6..793fc711a6 100644
--- a/config_server/v2/service/protov2/agent.pb.go
+++ b/config_server/v2/service/protov2/agent.pb.go
@@ -1,4 +1,3 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.35.1
 // 	protoc        v3.20.0
@@ -855,7 +854,7 @@ type HeartbeatResponse struct {
 	unknownFields protoimpl.UnknownFields
 
 	RequestId             []byte           `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
-	CommonResponse        *CommonResponse  `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`                        // Set common response
+	CommonResponse        *CommonResponse  `protobuf:"bytes,2,opt,name=commonResponse,proto3" json:"commonResponse,omitempty"`                                              // Set common response
 	Capabilities          uint64           `protobuf:"varint,3,opt,name=capabilities,proto3" json:"capabilities,omitempty"`                                                 // Bitmask of flags defined by ServerCapabilities enum
 	PipelineConfigUpdates []*ConfigDetail  `protobuf:"bytes,4,rep,name=pipeline_config_updates,json=pipelineConfigUpdates,proto3" json:"pipeline_config_updates,omitempty"` // Agent's pipeline config update status
 	InstanceConfigUpdates []*ConfigDetail  `protobuf:"bytes,5,rep,name=instance_config_updates,json=instanceConfigUpdates,proto3" json:"instance_config_updates,omitempty"` // Agent's instance config update status
@@ -1021,7 +1020,7 @@ type FetchConfigResponse struct {
 	unknownFields protoimpl.UnknownFields
 
 	RequestId      []byte          `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
-	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=common_response,json=commonResponse,proto3" json:"common_response,omitempty"`
+	CommonResponse *CommonResponse `protobuf:"bytes,2,opt,name=commonResponse,proto3" json:"commonResponse,omitempty"`
 	ConfigDetails  []*ConfigDetail `protobuf:"bytes,3,rep,name=config_details,json=configDetails,proto3" json:"config_details,omitempty"` // config detail
 }
 
@@ -1082,7 +1081,7 @@ type CommonResponse struct {
 	unknownFields protoimpl.UnknownFields
 
 	Status       int32  `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
-	ErrorMessage []byte `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"`
+	ErrorMessage []byte `protobuf:"bytes,2,opt,name=errorMessage,proto3" json:"errorMessage,omitempty"`
 }
 
 func (x *CommonResponse) Reset() {
@@ -1213,93 +1212,93 @@ var file_agent_proto_rawDesc = []byte{
 	0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52,
 	0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72,
 	0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x65, 0x78,
-	0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x92, 0x03, 0x0a, 0x11, 0x48, 0x65, 0x61,
+	0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x91, 0x03, 0x0a, 0x11, 0x48, 0x65, 0x61,
 	0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d,
 	0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a,
-	0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62,
-	0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63,
-	0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x17, 0x70,
-	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75,
-	0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x15, 0x70, 0x69, 0x70,
-	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74,
-	0x65, 0x73, 0x12, 0x45, 0x0a, 0x17, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61,
-	0x69, 0x6c, 0x52, 0x15, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x16, 0x63, 0x75, 0x73,
-	0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61,
-	0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
-	0x61, 0x6e, 0x64, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f,
-	0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12,
-	0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05,
-	0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18,
-	0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x22, 0x82, 0x01,
-	0x0a, 0x12, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
-	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
-	0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
-	0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x0b, 0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x72, 0x65, 0x71, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x13, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
-	0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65,
-	0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x4d, 0x0a, 0x0e, 0x43, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73,
-	0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73,
-	0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f,
-	0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2a, 0x40, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45,
-	0x54, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x50, 0x50, 0x4c, 0x59, 0x49, 0x4e, 0x47, 0x10,
-	0x01, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a,
-	0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x83, 0x01, 0x0a, 0x11, 0x41,
-	0x67, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73,
-	0x12, 0x1e, 0x0a, 0x1a, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x41,
-	0x67, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x10, 0x00,
-	0x12, 0x19, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x50, 0x69, 0x70, 0x65, 0x6c,
-	0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x41,
-	0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74,
-	0x73, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x04,
-	0x2a, 0x3a, 0x0a, 0x0c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73,
-	0x12, 0x1b, 0x0a, 0x17, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73,
-	0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0d, 0x0a,
-	0x09, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10, 0x01, 0x2a, 0xad, 0x01, 0x0a,
-	0x12, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
-	0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,
-	0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69,
-	0x74, 0x79, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x41,
-	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x65,
-	0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x10, 0x02, 0x12, 0x1f, 0x0a, 0x1b, 0x52,
-	0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a,
-	0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d,
-	0x6d, 0x61, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x10, 0x08, 0x2a, 0x80, 0x01, 0x0a,
-	0x0d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1c,
-	0x0a, 0x18, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x55,
-	0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f,
-	0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10,
-	0x01, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x65, 0x74, 0x63, 0x68, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69,
-	0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x10, 0x02,
-	0x12, 0x1d, 0x0a, 0x19, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
-	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x10, 0x04, 0x42,
-	0x0b, 0x5a, 0x09, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x76, 0x32, 0x3b, 0x62, 0x06, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x33,
+	0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x37, 0x0a,
+	0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69,
+	0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x63, 0x61,
+	0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x17, 0x70, 0x69,
+	0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x70,
+	0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x15, 0x70, 0x69, 0x70, 0x65,
+	0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+	0x73, 0x12, 0x45, 0x0a, 0x17, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x52, 0x15, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x16, 0x63, 0x75, 0x73, 0x74,
+	0x6f, 0x6d, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74,
+	0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
+	0x6e, 0x64, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d,
+	0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x14,
+	0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x66,
+	0x6c, 0x61, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, 0x08,
+	0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x22, 0x82, 0x01, 0x0a,
+	0x12, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69,
+	0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
+	0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x0b, 0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x72, 0x65, 0x71, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x73, 0x22, 0xa3, 0x01, 0x0a, 0x13, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d,
+	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x0f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x34, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x64, 0x65, 0x74, 0x61,
+	0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x4c, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f,
+	0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
+	0x73, 0x12, 0x22, 0x0a, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x2a, 0x40, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00,
+	0x12, 0x0c, 0x0a, 0x08, 0x41, 0x50, 0x50, 0x4c, 0x59, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0b,
+	0x0a, 0x07, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46,
+	0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x83, 0x01, 0x0a, 0x11, 0x41, 0x67, 0x65, 0x6e,
+	0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1e, 0x0a,
+	0x1a, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x41, 0x67, 0x65, 0x6e,
+	0x74, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x10, 0x00, 0x12, 0x19, 0x0a,
+	0x15, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65,
+	0x70, 0x74, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x43, 0x75,
+	0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x04, 0x2a, 0x3a, 0x0a,
+	0x0c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1b, 0x0a,
+	0x17, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x55, 0x6e, 0x73,
+	0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x75,
+	0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10, 0x01, 0x2a, 0xad, 0x01, 0x0a, 0x12, 0x53, 0x65,
+	0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73,
+	0x12, 0x1f, 0x0a, 0x1b, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x53,
+	0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x10,
+	0x00, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x41, 0x74, 0x74, 0x72,
+	0x69, 0x62, 0x75, 0x74, 0x65, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x62, 0x65,
+	0x72, 0x73, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x10, 0x02, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x62,
+	0x65, 0x72, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x65, 0x6d,
+	0x62, 0x65, 0x72, 0x73, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+	0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x10, 0x08, 0x2a, 0x80, 0x01, 0x0a, 0x0d, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1c, 0x0a, 0x18, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x55, 0x6e, 0x73, 0x70,
+	0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x65, 0x70,
+	0x6f, 0x72, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10, 0x01, 0x12, 0x1d,
+	0x0a, 0x19, 0x46, 0x65, 0x74, 0x63, 0x68, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x10, 0x02, 0x12, 0x1d, 0x0a,
+	0x19, 0x46, 0x65, 0x74, 0x63, 0x68, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x10, 0x04, 0x42, 0x0b, 0x5a, 0x09,
+	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x76, 0x32, 0x3b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x33,
 }
 
 var (
@@ -1344,12 +1343,12 @@ var file_agent_proto_depIdxs = []int32{
 	6,  // 5: HeartbeatRequest.pipeline_configs:type_name -> ConfigInfo
 	6,  // 6: HeartbeatRequest.instance_configs:type_name -> ConfigInfo
 	7,  // 7: HeartbeatRequest.custom_commands:type_name -> CommandInfo
-	15, // 8: HeartbeatResponse.common_response:type_name -> CommonResponse
+	15, // 8: HeartbeatResponse.commonResponse:type_name -> CommonResponse
 	10, // 9: HeartbeatResponse.pipeline_config_updates:type_name -> ConfigDetail
 	10, // 10: HeartbeatResponse.instance_config_updates:type_name -> ConfigDetail
 	11, // 11: HeartbeatResponse.custom_command_updates:type_name -> CommandDetail
 	6,  // 12: FetchConfigRequest.req_configs:type_name -> ConfigInfo
-	15, // 13: FetchConfigResponse.common_response:type_name -> CommonResponse
+	15, // 13: FetchConfigResponse.commonResponse:type_name -> CommonResponse
 	10, // 14: FetchConfigResponse.config_details:type_name -> ConfigDetail
 	15, // [15:15] is the sub-list for method output_type
 	15, // [15:15] is the sub-list for method input_type
diff --git a/config_server/v2/service/router/router.go b/config_server/v2/service/router/router.go
index 23d3de83f2..f04d8b9c9e 100644
--- a/config_server/v2/service/router/router.go
+++ b/config_server/v2/service/router/router.go
@@ -15,7 +15,6 @@ func initUserRouter(router *gin.Engine) {
 		userRouter.POST("/ListAgentGroups", handler.ListAgentGroups)
 		userRouter.POST("/ListAgents", handler.ListAgentsInGroup)
 		userRouter.POST("/GetAppliedPipelineConfigsForAgentGroup", handler.GetAppliedPipelineConfigsForAgentGroup)
-		userRouter.POST("/GetAppliedInstanceConfigsForAgentGroup", handler.GetAppliedInstanceConfigsForAgentGroup)
 
 		userRouter.POST("/CreatePipelineConfig", handler.CreatePipelineConfig)
 		userRouter.POST("/UpdatePipelineConfig", handler.UpdatePipelineConfig)
@@ -26,16 +25,6 @@ func initUserRouter(router *gin.Engine) {
 		userRouter.POST("/RemovePipelineConfigFromAgentGroup", handler.RemovePipelineConfigFromAgentGroup)
 		userRouter.POST("/GetAppliedAgentGroupsWithPipelineConfig", handler.GetAppliedAgentGroupsWithPipelineConfig)
 		userRouter.POST("/GetPipelineConfigStatusList", handler.GetPipelineConfigStatusList)
-
-		userRouter.POST("/CreateInstanceConfig", handler.CreateInstanceConfig)
-		userRouter.POST("/UpdateInstanceConfig", handler.UpdateInstanceConfig)
-		userRouter.POST("/DeleteInstanceConfig", handler.DeleteInstanceConfig)
-		userRouter.POST("/GetInstanceConfig", handler.GetInstanceConfig)
-		userRouter.POST("/ListInstanceConfigs", handler.ListInstanceConfigs)
-		userRouter.POST("/ApplyInstanceConfigToAgentGroup", handler.ApplyInstanceConfigToAgentGroup)
-		userRouter.POST("/RemoveInstanceConfigFromAgentGroup", handler.RemoveInstanceConfigFromAgentGroup)
-		userRouter.POST("/GetAppliedAgentGroupsWithInstanceConfig", handler.GetAppliedAgentGroupsWithInstanceConfig)
-		userRouter.POST("/GetInstanceConfigStatusList", handler.GetInstanceConfigStatusList)
 	}
 
 }
@@ -45,7 +34,6 @@ func initAgentRouter(router *gin.Engine) {
 	{
 		agentRouter.POST("/Heartbeat", handler.HeartBeat)
 		agentRouter.POST("/FetchPipelineConfig", handler.FetchPipelineConfig)
-		agentRouter.POST("/FetchInstanceConfig", handler.FetchInstanceConfig)
 	}
 	handler.CheckAgentExist()
 }
diff --git a/config_server/v2/service/utils/environment.go b/config_server/v2/service/utils/environment.go
index 72bbc4ac3a..6704e52425 100644
--- a/config_server/v2/service/utils/environment.go
+++ b/config_server/v2/service/utils/environment.go
@@ -8,7 +8,7 @@ import (
 func GetEnvName() (string, error) {
 	name := os.Getenv("GO_ENV")
 	if name == "" {
-		name = "dev"
+		name = "prod"
 	}
 	log.Printf("the environment is %s", name)
 	return name, nil

From e601b736814c3c99b4827633ab406347d1bc3a24 Mon Sep 17 00:00:00 2001
From: ww67652 <1749113286@qq.com>
Date: Wed, 30 Oct 2024 20:28:08 +0800
Subject: [PATCH 10/11] fix: refactor directory

---
 config_server/v2/deployment/.env              |  5 --
 config_server/v2/deployment/Dockerfile-Agent  | 18 -------
 config_server/v2/deployment/README.md         | 38 -------------
 .../v2/deployment/docker-compose.yml          | 54 -------------------
 .../deployment/ilogtail_config.template.json  |  8 ---
 5 files changed, 123 deletions(-)
 delete mode 100644 config_server/v2/deployment/.env
 delete mode 100755 config_server/v2/deployment/Dockerfile-Agent
 delete mode 100644 config_server/v2/deployment/README.md
 delete mode 100644 config_server/v2/deployment/docker-compose.yml
 delete mode 100644 config_server/v2/deployment/ilogtail_config.template.json

diff --git a/config_server/v2/deployment/.env b/config_server/v2/deployment/.env
deleted file mode 100644
index d99ed73a9e..0000000000
--- a/config_server/v2/deployment/.env
+++ /dev/null
@@ -1,5 +0,0 @@
-CONFIG_SERVER=../service
-CONFIG_SERVER_UI=../ui
-
-# 需把该目录下的Dockerfile-agent复制到agent对应的目录下,并修改${AGENT}为agent所在目录路径
-AGENT=/home/source-code
\ No newline at end of file
diff --git a/config_server/v2/deployment/Dockerfile-Agent b/config_server/v2/deployment/Dockerfile-Agent
deleted file mode 100755
index b04424d8f8..0000000000
--- a/config_server/v2/deployment/Dockerfile-Agent
+++ /dev/null
@@ -1,18 +0,0 @@
-FROM centos:7
-
-RUN curl -L -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo \
-    && yum update -y \
-    && yum upgrade -y \
-    && yum -y clean all \
-    && rm -fr /var/cache \
-    && rm -rf /core.* \
-    && yum install -y gettext
-
-WORKDIR /agent
-COPY . .
-
-CMD envsubst < ilogtail_config.template.json > ilogtail_config.json \
-    && sh -c ./ilogtail > stdout.log 2> stderr.log
-
-
-
diff --git a/config_server/v2/deployment/README.md b/config_server/v2/deployment/README.md
deleted file mode 100644
index b9fdb62857..0000000000
--- a/config_server/v2/deployment/README.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# 部署说明
-
-本项目实现了config-server的后端(config-server)与前端(config-server-ui),并基于docker与docker-compose的方式进行部署
-
-## 快速开始
-
-进入`deployment`目录,运行`deployment-compose.yml`,启动三个容器(`mysql`、`config-server`、`config-server-ui`)
-
-```shell
-docker compose -f docker-compose.yml up -d
-```
-
-启动成功后,通过`http://{your-ip}:8080`即可实现前端页面的访问
-
-## Agent启动
-
-由于最新版本的[ilogtail](https://github.com/alibaba/ilogtail/releases/tag/v2.0.7)(截止到2.0.7)尚未提供支持v2心跳的功能,为了便于使用(测试)`config-server-ui`,本项目提供了基于docker启动Agent的脚本,复制`Dockefile-Agent`与`ilogtail_config.template.json`到Agent的目录下,
-修改`.env`中的`${AGENT}`为Agent所在目录路径(Agent安装与启动见[quick-start](https://github.com/alibaba/ilogtail/blob/main/docs/cn/installation/quick-start.md)),并在`docker-compose.yml`添加
-```yml
-  agent:
-    build:
-      context: ${AGENT}
-      dockerfile: Dockerfile-Agent
-    image: ilogtail:openSource
-    environment:
-      CONFIG_SERVER_ADDRESSES: '["config-server:9090"]'
-      TZ: Asia/Shanghai
-    deploy:
-      replicas: 3
-    networks:
-      - server
-```
-
-再次运行下面的命令,这将会启动3个ilogtail Agent。
-
-```shell
-docker compose -f docker-compose.yml up -d
-```
\ No newline at end of file
diff --git a/config_server/v2/deployment/docker-compose.yml b/config_server/v2/deployment/docker-compose.yml
deleted file mode 100644
index 7a6c893fb3..0000000000
--- a/config_server/v2/deployment/docker-compose.yml
+++ /dev/null
@@ -1,54 +0,0 @@
-version: '3.8'
-services:
-  mysql:
-    image: mysql:latest
-    volumes:
-      - /var/lib/mysql:/var/lib/mysql
-    ports:
-      - "3306:3306"
-    environment:
-      MYSQL_ROOT_PASSWORD: "123456"
-    cap_add:
-      - SYS_NICE
-    healthcheck:
-      test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ]
-      interval: 10s
-      retries: 5
-      timeout: 5s
-    networks:
-      - server
-
-  config-server:
-    build:
-      context: ${CONFIG_SERVER}
-      dockerfile: Dockerfile
-    # 如果之前构建过镜像,再次docker compose则不会重新构建
-    image: config-server:openSource
-    ports:
-      - "9090:9090"
-    environment:
-      TZ: Asia/Shanghai
-    extra_hosts:
-      - "host.docker.internal:host-gateway"
-    networks:
-      - server
-    depends_on:
-      mysql:
-        condition: service_healthy
-
-  config-server-ui:
-    build:
-      context: ${CONFIG_SERVER_UI}
-      dockerfile: Dockerfile
-    image: config-server-ui:openSource
-    ports:
-      - "8080:8080"
-    environment:
-      TZ: Asia/Shanghai
-    extra_hosts:
-      - "host.docker.internal:host-gateway"
-    networks:
-      - server
-#替换成你自己的网络
-networks:
-  server:
diff --git a/config_server/v2/deployment/ilogtail_config.template.json b/config_server/v2/deployment/ilogtail_config.template.json
deleted file mode 100644
index eaf828bb58..0000000000
--- a/config_server/v2/deployment/ilogtail_config.template.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "config_server_list" : [
-    {
-      "cluster":"community",
-      "endpoint_list":$CONFIG_SERVER_ADDRESSES
-    }
-  ]
-}
\ No newline at end of file

From a7bb70befb2df72147834f565714b9b8c38ac923 Mon Sep 17 00:00:00 2001
From: ww67652 <1749113286@qq.com>
Date: Wed, 30 Oct 2024 20:51:17 +0800
Subject: [PATCH 11/11] fix: solve conflict

---
 config_server/protocol/v2/README.md | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/config_server/protocol/v2/README.md b/config_server/protocol/v2/README.md
index 7d588a5348..129cc14f40 100644
--- a/config_server/protocol/v2/README.md
+++ b/config_server/protocol/v2/README.md
@@ -22,7 +22,7 @@
         string running_status = 8;                  // Human readable running status
         int64 startup_time = 9;                     // Required, Agent's startup time
         repeated ConfigInfo pipeline_configs = 10;  // Information about the current PIPELINE_CONFIG held by the Agent
-        repeated ConfigInfo process_configs = 11;   // Information about the current AGENT_CONFIG held by the Agent
+        repeated ConfigInfo instance_configs = 11;   // Information about the current AGENT_CONFIG held by the Agent
         repeated CommandInfo custom_commands = 12;  // Information about command history
         uint64 flags = 13;                          // Predefined command flag
         bytes opaque = 14;                          // Opaque data for extension
@@ -74,7 +74,7 @@
         UnspecifiedAgentCapability = 0;
         // The Agent can accept pipeline configuration from the Server.
         AcceptsPipelineConfig          = 0x00000001;
-        // The Agent can accept process configuration from the Server.
+        // The Agent can accept instance configuration from the Server.
         AcceptsInstanceConfig           = 0x00000002;
         // The Agent can accept custom command from the Server.
         AcceptsCustomCommand           = 0x00000004;
@@ -100,7 +100,7 @@
         uint64 capabilities = 3;                            // Bitmask of flags defined by ServerCapabilities enum
 
         repeated ConfigDetail pipeline_config_updates = 4;  // Agent's pipeline config update status
-        repeated ConfigDetail process_config_updates = 5;   // Agent's process config update status
+        repeated ConfigDetail instance_config_updates = 5;   // Agent's instance config update status
         repeated CommandDetail custom_command_updates = 6;  // Agent's commands updates
         uint64 flags = 7;                                   // Predefined command flag
         bytes opaque = 8;                                   // Opaque data for extension
@@ -126,7 +126,7 @@
         RembersAttribute                   = 0x00000001;
         // The Server can remember pipeline config status.
         RembersPipelineConfigStatus        = 0x00000002;
-        // The Server can remember process config status.
+        // The Server can remember instance config status.
         RembersInstanceConfigStatus         = 0x00000004;
         // The Server can remember custom command status.
         RembersCustomCommandStatus         = 0x00000008;
@@ -168,7 +168,7 @@ Server:应当通过capbilitiies上报Server自身的能力,这样如果新
 
 Client:Agent启动后第一次向Server汇报全量信息,request字段应填尽填。request\_id、sequence\_num、capabilities、instance\_id、agent\_type、startup\_time为必填字段。
 
-Server:Server根据上报的信息返回响应。pipeline\_config\_updates、process\_config\_updates中包含agent需要同步的配置,updates中必然包含name和version,是否包含详情context和detail取决于server端实现。custom\_command_updates包含要求agent执行的命令command中必然包含type、name和expire\_time。
+Server:Server根据上报的信息返回响应。pipeline\_config\_updates、instance\_config\_updates中包含agent需要同步的配置,updates中必然包含name和version,是否包含详情context和detail取决于server端实现。custom\_command_updates包含要求agent执行的命令command中必然包含type、name和expire\_time。
 
 Server是否保存Client信息取决于Server实现,如果服务端找不到或保存的sequence\_num + 1 ≠ 心跳的sequence\_num,那么就立刻返回并且flags中必须设置ReportFullStatus标识位。
 
@@ -192,13 +192,13 @@ Server:同注册
 
 ### 进程配置
 
-若Server的注册/心跳响应中有process\_config\_updates.detail
+若Server的注册/心跳响应中有instance\_config\_updates.detail
 
 Client:直接从response中获得detail,应用成功后下次心跳需要上报完整状态。
 
 若Server的响应不包含detail
 
-Client:根据process\_config\_updates的信息构造FetchInstanceConfigRequest
+Client:根据instance\_config\_updates的信息构造FetchInstanceConfigRequest
 
 Server:返回FetchInstanceConfigResponse