This is an automated email from the ASF dual-hosted git repository.

hefengen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 8813473d35 [type:feat] add ai prompt plugin (#5962)
8813473d35 is described below

commit 8813473d357147722b49d5a10ee07ccb24794ed8
Author: aias00 <liuhon...@apache.org>
AuthorDate: Wed Mar 26 14:48:55 2025 +0800

    [type:feat] add ai prompt plugin (#5962)
    
    * [feat] add ai prompt plugin
    
    * [feat] refactor ai proxy plugin
    
    * [feat] refactor ai proxy plugin
    
    * [feat] add ai prompt plugin
    
    * [feat] add ai prompt plugin sql
    
    * [feat] add ai prompt plugin sql
---
 db/init/mysql/schema.sql                           |  38 ++++++
 db/init/ob/schema.sql                              |  41 +++++-
 db/init/og/create-table.sql                        |  26 +++-
 db/init/oracle/schema.sql                          |  91 ++++++++++++-
 db/init/pg/create-table.sql                        |  37 +++++-
 db/upgrade/2.7.0-upgrade-2.7.1-mysql.sql           |  42 +++++-
 db/upgrade/2.7.0-upgrade-2.7.1-ob.sql              |  40 +++++-
 db/upgrade/2.7.0-upgrade-2.7.1-og.sql              |  39 +++++-
 db/upgrade/2.7.0-upgrade-2.7.1-oracle.sql          |  93 +++++++++++++-
 db/upgrade/2.7.0-upgrade-2.7.1-pg.sql              |  39 +++++-
 .../src/main/resources/sql-script/h2/schema.sql    |  16 +++
 shenyu-bootstrap/pom.xml                           |   8 ++
 .../apache/shenyu/common/constant/Constants.java   |  14 +-
 .../common/dto/convert/plugin/AiPromptConfig.java  | 142 +++++++++++++++++++++
 .../common/dto/convert/plugin/AiProxyConfig.java   |  40 ++----
 .../common/dto/convert/rule/AiPromptHandle.java    | 142 +++++++++++++++++++++
 .../common/dto/convert/rule/AiProxyHandle.java     |  40 ++----
 .../org/apache/shenyu/common/enums/PluginEnum.java |   5 +
 shenyu-plugin/pom.xml                              |   1 +
 shenyu-plugin/shenyu-plugin-ai-prompt/pom.xml      |  36 ++++++
 .../shenyu/plugin/ai/prompt/AiPromptPlugin.java    | 136 ++++++++++++++++++++
 .../prompt/handler/AiPromptPluginDataHandler.java  |  71 +++++++++++
 .../shenyu/plugin/ai/proxy/AiProxyPlugin.java      |  10 +-
 .../plugin/ai/proxy/strategy/openai/OpenAI.java    |   1 -
 .../shenyu-spring-boot-starter-plugin/pom.xml      |   2 +
 .../pom.xml                                        |  35 +++++
 .../ai/prompt/AiPromptPluginConfiguration.java     |  57 +++++++++
 .../src/main/resources/META-INF/spring.factories   |  19 +++
 .../src/main/resources/META-INF/spring.provides    |  18 +++
 ...rk.boot.autoconfigure.AutoConfiguration.imports |  18 +++
 30 files changed, 1221 insertions(+), 76 deletions(-)

diff --git a/db/init/mysql/schema.sql b/db/init/mysql/schema.sql
index b2f1889caf..b80037fff1 100644
--- a/db/init/mysql/schema.sql
+++ b/db/init/mysql/schema.sql
@@ -871,6 +871,17 @@ INSERT INTO `permission` VALUES ('1697146860569542748', 
'1346358560427216896', '
 INSERT INTO `permission` VALUES ('1697146860569542749', '1346358560427216896', 
'1844026099075534857', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
 INSERT INTO `permission` VALUES ('1697146860569542750', '1346358560427216896', 
'1844026099075534858', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
 
+INSERT INTO `permission` VALUES ('1697146860569642741', '1346358560427216896', 
'1844026099075554850', '2023-08-31 06:59:01', '2023-08-31 06:59:01');
+INSERT INTO `permission` VALUES ('1697146860569642742', '1346358560427216896', 
'1844026099075554851', '2023-08-31 07:22:07', '2023-08-31 07:22:07');
+INSERT INTO `permission` VALUES ('1697146860569642743', '1346358560427216896', 
'1844026099075554852', '2023-08-31 07:14:26', '2023-08-31 07:14:26');
+INSERT INTO `permission` VALUES ('1697146860569642744', '1346358560427216896', 
'1844026099075554853', '2023-08-31 07:22:07', '2023-08-31 07:22:07');
+INSERT INTO `permission` VALUES ('1697146860569642745', '1346358560427216896', 
'1844026099075554854', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642746', '1346358560427216896', 
'1844026099075554855', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642747', '1346358560427216896', 
'1844026099075554856', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642748', '1346358560427216896', 
'1844026099075554857', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642749', '1346358560427216896', 
'1844026099075554858', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642750', '1346358560427216896', 
'1844026099075554859', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+
 INSERT INTO `permission` VALUES ('1697146860569542751', '1346358560427216896', 
'1844026099075534859', '2023-08-31 06:59:01', '2023-08-31 06:59:01');
 INSERT INTO `permission` VALUES ('1697146860569542752', '1346358560427216896', 
'1844026099075534860', '2023-08-31 07:22:07', '2023-08-31 07:22:07');
 INSERT INTO `permission` VALUES ('1697146860569542753', '1346358560427216896', 
'1844026099075534861', '2023-08-31 07:14:26', '2023-08-31 07:14:26');
@@ -947,6 +958,8 @@ INSERT INTO `plugin` VALUES ('45', 'loggingRabbitMQ', 
'{\"host\":\"127.0.0.1\",\
 INSERT INTO `plugin` VALUES ('50', 'aiProxy', 
'{"provider":"OpenAI","baseUrl":"https://api.openai.com/v1/chat/completions","model":"gpt-4o-mini","apiKey":"your_api_key","temperature":"0.5","maxTokens":"1000","stream":"false","prompt":""}',
 'Ai', 199, 0, '2023-12-20 18:02:53', '2023-12-20 18:02:53', null);
 INSERT INTO `plugin` VALUES ('51', 'aiTokenLimiter', NULL, 'Ai', 171, 0, 
'2023-12-20 18:02:53', '2023-12-20 18:02:53', null);
 
+INSERT INTO `plugin` VALUES ('52', 'aiPrompt', null, 'Ai', 170, 0, '2023-12-20 
18:02:53', '2023-12-20 18:02:53', null);
+
 -- ----------------------------
 -- Table structure for plugin_handle
 -- ----------------------------
@@ -1338,6 +1351,11 @@ INSERT INTO `plugin_handle` VALUES 
('1722804548510507046', '50', 'maxTokens', 'm
 INSERT INTO `plugin_handle` VALUES ('1722804548510507047', '50', 'stream', 
'stream', 3, 1, 6, '{\"defaultValue\":\"false\",\"rule\":\"\"}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 INSERT INTO `plugin_handle` VALUES ('1722804548510507048', '50', 'prompt', 
'prompt', 2, 1, 7, '{\"required\":\"0\",\"rule\":\"\"}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 
+INSERT INTO plugin_handle VALUES ('1722804548510507140', '52', 'prepend', 
'prepend', 2, 3, 1, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+INSERT INTO plugin_handle VALUES ('1722804548510507141', '52', 'preRole', 
'preRole', 3, 3, 2, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+INSERT INTO plugin_handle VALUES ('1722804548510507142', '52', 'append', 
'append', 2, 3, 3, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+INSERT INTO plugin_handle VALUES ('1722804548510507143', '52', 'postRole', 
'postRole', 3, 3, 4, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+
 INSERT INTO `plugin_handle` VALUES ('1722804548510507049', '51', 'database', 
'database', 1, 3, 2, 
'{\"required\":\"0\",\"defaultValue\":\"0\",\"rule\":\"\"}', '2022-05-25 
18:02:53', '2022-05-25 18:02:53');
 INSERT INTO `plugin_handle` VALUES ('1722804548510507050', '51', 'master', 
'master', 2, 3, 3, '{\"required\":\"0\",\"rule\":\"\"}', '2022-05-25 18:02:53', 
'2022-05-25 18:02:53');
 INSERT INTO `plugin_handle` VALUES ('1722804548510507051', '51', 'mode', 
'mode', 2, 3, 4, 
'{\"required\":\"0\",\"defaultValue\":\"standalone\",\"rule\":\"\"}', 
'2022-05-25 18:02:53', '2022-05-25 18:02:53');
@@ -1351,6 +1369,7 @@ INSERT INTO `plugin_handle` VALUES 
('1899702350766538752', '51', 'aiTokenLimitTy
 INSERT INTO `plugin_handle` VALUES ('1899702411294539776', '51', 
'timeWindowSeconds', 'timeWindowSeconds', 1, 2, 1, 
'{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 06:02:04.155', '2025-03-12 
06:02:04.155');
 INSERT INTO `plugin_handle` VALUES ('1899702472330051584', '51', 'keyName', 
'keyName', 2, 2, 2, '{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 
06:02:18.707', '2025-03-12 06:02:18.707');
 INSERT INTO `plugin_handle` VALUES ('1899702529972371456', '51', 'tokenLimit', 
'tokenLimit', 1, 2, 3, '{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
+
 -- ----------------------------
 -- Table structure for resource
 -- ----------------------------
@@ -1897,6 +1916,18 @@ INSERT INTO `resource` VALUES ('1844026099075534856', 
'1844026099075534849', 'SH
 INSERT INTO `resource` VALUES ('1844026099075534857', '1844026099075534849', 
'SHENYU.BUTTON.PLUGIN.RULE.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiProxyRule:delete', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
 INSERT INTO `resource` VALUES ('1844026099075534858', '1844026099075534849', 
'SHENYU.BUTTON.PLUGIN.SYNCHRONIZE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiProxy:modify', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
 
+INSERT INTO `resource` VALUES ('1844026099075554850', '1346775491550474240', 
'aiPrompt', 'aiPrompt', '/plug/aiPrompt', 'aiPrompt', 1, 0, 'pic-center', 0, 0, 
'', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554851', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:add', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554852', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:query', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554853', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.EDIT', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:edit', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554854', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:delete', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554855', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:add', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554856', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:query', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554857', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.EDIT', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:edit', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554858', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:delete', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554859', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SYNCHRONIZE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPrompt:modify', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+
+
 INSERT INTO `resource` VALUES ('1844026099075534859', '1346775491550474240', 
'aiTokenLimiter', 'aiTokenLimiter', '/plug/aiTokenLimiter', 'aiTokenLimiter', 
1, 0, 'pic-center', 0, 0, '', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
 INSERT INTO `resource` VALUES ('1844026099075534860', '1844026099075534859', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiTokenLimiterSelector:add', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
 INSERT INTO `resource` VALUES ('1844026099075534861', '1844026099075534859', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiTokenLimiterSelector:query', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
@@ -2156,6 +2187,11 @@ INSERT INTO `shenyu_dict` VALUES ('1679002911061737484', 
'provider', 'PROVIDER_T
 INSERT INTO `shenyu_dict` VALUES ('1679002911061737485', 'provider', 
'PROVIDER_TYPE_OPENAPI', 'OpenAPI', 'OpenAPI', 'OpenAPI', 3, 1, '2024-02-07 
14:31:49', '2024-02-07 14:31:49');
 INSERT INTO `shenyu_dict` VALUES ('1679002911061737486', 'provider', 
'PROVIDER_TYPE_ALIYUN', 'ALiYun', 'ALiYun', 'ALiYun', 4, 1, '2024-02-07 
14:31:49', '2024-02-07 14:31:49');
 
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737580', 'preRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737581', 'preRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737582', 'postRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737583', 'postRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+
 INSERT INTO `shenyu_dict` VALUES ('1679002911061737490', 'aiTokenLimitType', 
'DEFAULT_KEY_RESOLVER', 'default', 'default', 'Rate limit by default', 0, 1, 
'2024-02-07 14:31:49', '2024-02-07 14:31:49');
 INSERT INTO `shenyu_dict` VALUES ('1679002911061737491', 'aiTokenLimitType', 
'IP_KEY_RESOLVER', 'ip', 'ip', 'Rate limit by request ip', 1, 1, '2024-02-07 
14:31:49', '2024-02-07 14:31:49');
 INSERT INTO `shenyu_dict` VALUES ('1679002911061737492', 'aiTokenLimitType', 
'URI_KEY_RESOLVER', 'uri', 'uri', 'Rate limit by request uri', 2, 1, 
'2024-02-07 14:31:49', '2024-02-07 14:31:49');
@@ -2460,6 +2496,8 @@ INSERT INTO `namespace_plugin_rel` 
(`id`,`namespace_id`,`plugin_id`, `config`, `
 INSERT INTO `namespace_plugin_rel` (`id`,`namespace_id`,`plugin_id`, `config`, 
`sort`, `enabled`, `date_created`, `date_updated`) VALUES 
('1801816010882822187','649330b6-c2d7-4edc-be8e-8a54df9eb385','50', 
'{\"provider\":\"OpenAI\",\"baseUrl\":\"https://api.openai.com/v1/chat/completions\",\"model\":\"gpt-4o-mini\",\"apiKey\":\"your_api_key\",\"temperature\":\"0.5\",\"maxTokens\":\"1000\",\"stream\":\"false\",\"prompt\":\"\"}',
 199, 0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
 INSERT INTO `namespace_plugin_rel` (`id`,`namespace_id`,`plugin_id`, `config`, 
`sort`, `enabled`, `date_created`, `date_updated`) VALUES 
('1801816010882822188','649330b6-c2d7-4edc-be8e-8a54df9eb385','51', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
 
+INSERT INTO `namespace_plugin_rel` (`id`,`namespace_id`,`plugin_id`, `config`, 
`sort`, `enabled`, `date_created`, `date_updated`) VALUES 
('1801816010882822189','649330b6-c2d7-4edc-be8e-8a54df9eb385','52', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
+
 
 INSERT INTO `resource` (`id`, `parent_id`, `title`, `name`, `url`, 
`component`, `resource_type`, `sort`, `icon`, `is_leaf`, `is_route`, `perms`, 
`status`, `date_created`, `date_updated`) VALUES ('1792749362445840479', 
'1357956838021890048', 'SHENYU.MENU.SYSTEM.MANAGMENT.NAMESPACEPLUGIN', 
'namespacePlugin', '/config/namespacePlugin', 'namespacePlugin', 1, 2, 'build', 
0, 0, '', 1, '2024-06-25 18:02:53.000', '2024-06-25 18:02:53.000');
 INSERT INTO `resource` (`id`, `parent_id`, `title`, `name`, `url`, 
`component`, `resource_type`, `sort`, `icon`, `is_leaf`, `is_route`, `perms`, 
`status`, `date_created`, `date_updated`) VALUES ('1792749362445840480', 
'1792749362445840479', 'SHENYU.BUTTON.SYSTEM.LIST', '', '', '', 2, 0, '', 1, 0, 
'system:namespacePlugin:list', 1, '2024-06-25 18:02:53.000', '2024-06-25 
18:02:53.000');
diff --git a/db/init/ob/schema.sql b/db/init/ob/schema.sql
index 14fa45a6cc..971c24f347 100644
--- a/db/init/ob/schema.sql
+++ b/db/init/ob/schema.sql
@@ -2467,6 +2467,45 @@ CREATE TABLE `namespace_user_rel` (
                                       `date_updated` timestamp NOT NULL 
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'date_updated'
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci 
COMMENT='namespace user relation ';
 
+INSERT INTO `permission` VALUES ('1697146860569642741', '1346358560427216896', 
'1844026099075554850', '2023-08-31 06:59:01', '2023-08-31 06:59:01');
+INSERT INTO `permission` VALUES ('1697146860569642742', '1346358560427216896', 
'1844026099075554851', '2023-08-31 07:22:07', '2023-08-31 07:22:07');
+INSERT INTO `permission` VALUES ('1697146860569642743', '1346358560427216896', 
'1844026099075554852', '2023-08-31 07:14:26', '2023-08-31 07:14:26');
+INSERT INTO `permission` VALUES ('1697146860569642744', '1346358560427216896', 
'1844026099075554853', '2023-08-31 07:22:07', '2023-08-31 07:22:07');
+INSERT INTO `permission` VALUES ('1697146860569642745', '1346358560427216896', 
'1844026099075554854', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642746', '1346358560427216896', 
'1844026099075554855', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642747', '1346358560427216896', 
'1844026099075554856', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642748', '1346358560427216896', 
'1844026099075554857', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642749', '1346358560427216896', 
'1844026099075554858', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642750', '1346358560427216896', 
'1844026099075554859', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+
+
+INSERT INTO `plugin` VALUES ('52', 'aiPrompt', null, 'Ai', 170, 0, '2023-12-20 
18:02:53', '2023-12-20 18:02:53', null);
+
+
+INSERT INTO plugin_handle VALUES ('1722804548510507140', '52', 'prepend', 
'prepend', 2, 3, 1, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+INSERT INTO plugin_handle VALUES ('1722804548510507141', '52', 'preRole', 
'preRole', 3, 3, 2, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+INSERT INTO plugin_handle VALUES ('1722804548510507142', '52', 'append', 
'append', 2, 3, 3, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+INSERT INTO plugin_handle VALUES ('1722804548510507143', '52', 'postRole', 
'postRole', 3, 3, 4, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+
+
+INSERT INTO `resource` VALUES ('1844026099075554850', '1346775491550474240', 
'aiPrompt', 'aiPrompt', '/plug/aiPrompt', 'aiPrompt', 1, 0, 'pic-center', 0, 0, 
'', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554851', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:add', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554852', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:query', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554853', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.EDIT', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:edit', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554854', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:delete', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554855', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:add', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554856', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:query', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554857', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.EDIT', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:edit', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554858', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:delete', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554859', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SYNCHRONIZE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPrompt:modify', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737580', 'preRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737581', 'preRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737582', 'postRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737583', 'postRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+
+INSERT INTO `namespace_plugin_rel` (`id`,`namespace_id`,`plugin_id`, `config`, 
`sort`, `enabled`, `date_created`, `date_updated`) VALUES 
('1801816010882822189','649330b6-c2d7-4edc-be8e-8a54df9eb385','52', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
+
 
 INSERT INTO `shenyu_dict` VALUES ('1679002911061737490', 'aiTokenLimitType', 
'DEFAULT_KEY_RESOLVER', 'default', 'default', 'Rate limit by default', 0, 1, 
'2024-02-07 14:31:49', '2024-02-07 14:31:49');
 INSERT INTO `shenyu_dict` VALUES ('1679002911061737491', 'aiTokenLimitType', 
'IP_KEY_RESOLVER', 'ip', 'ip', 'Rate limit by request ip', 1, 1, '2024-02-07 
14:31:49', '2024-02-07 14:31:49');
@@ -2478,4 +2517,4 @@ INSERT INTO `shenyu_dict` VALUES ('1679002911061737495', 
'aiTokenLimitType', 'CO
 INSERT INTO `plugin_handle` VALUES ('1899702350766538752', '51', 
'aiTokenLimitType', 'aiTokenLimitType', 3, 2, 0, 
'{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 06:01:49.725', '2025-03-12 
06:07:49.856');
 INSERT INTO `plugin_handle` VALUES ('1899702411294539776', '51', 
'timeWindowSeconds', 'timeWindowSeconds', 1, 2, 1, 
'{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 06:02:04.155', '2025-03-12 
06:02:04.155');
 INSERT INTO `plugin_handle` VALUES ('1899702472330051584', '51', 'keyName', 
'keyName', 2, 2, 2, '{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 
06:02:18.707', '2025-03-12 06:02:18.707');
-INSERT INTO `plugin_handle` VALUES ('1899702529972371456', '51', 'tokenLimit', 
'tokenLimit', 1, 2, 3, '{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
\ No newline at end of file
+INSERT INTO `plugin_handle` VALUES ('1899702529972371456', '51', 'tokenLimit', 
'tokenLimit', 1, 2, 3, '{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
diff --git a/db/init/og/create-table.sql b/db/init/og/create-table.sql
index 7f5a361229..b4ab865232 100644
--- a/db/init/og/create-table.sql
+++ b/db/init/og/create-table.sql
@@ -2843,6 +2843,30 @@ INSERT INTO "public"."plugin_handle" VALUES 
('1722804548510507046', '50', 'maxTo
 INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507047', '50', 
'stream', 'stream', 3, 1, 6, '{"defaultValue":"false","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507048', '50', 
'prompt', 'prompt', 2, 1, 7, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 
+INSERT INTO "public"."plugin" VALUES ('52', 'aiPrompt', null, 'Ai', 170, 0, 
'2023-12-20 18:02:53', '2023-12-20 18:02:53', null);
+
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507140', '52', 
'prepend', 'prepend', 2, 3, 1, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507141', '52', 
'preRole', 'preRole', 3, 3, 2, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507142', '52', 
'append', 'append', 2, 3, 3, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507143', '52', 
'postRole', 'postRole', 3, 3, 4, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+
+INSERT INTO "public"."resource" VALUES ('1844026099075554850', 
'1346775491550474240', 'aiPrompt', 'aiPrompt', '/plug/aiPrompt', 'aiPrompt', 1, 
0, 'pic-center', 0, 0, '', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554851', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptSelector:add', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554852', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.QUERY', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptSelector:query', 1, '2022-05-25 18:02:58', 
'2022-05-25 18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554853', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.EDIT', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptSelector:edit', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554854', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.DELETE', '', '', '', 2, 
0, '', 1, 0, 'plugin:aiPromptSelector:delete', 1, '2022-05-25 18:02:58', 
'2022-05-25 18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554855', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.ADD', '', '', '', 2, 0, '', 
1, 0, 'plugin:aiPromptRule:add', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554856', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.QUERY', '', '', '', 2, 0, '', 
1, 0, 'plugin:aiPromptRule:query', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554857', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.EDIT', '', '', '', 2, 0, '', 
1, 0, 'plugin:aiPromptRule:edit', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554858', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.DELETE', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptRule:delete', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554859', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SYNCHRONIZE', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPrompt:modify', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737580', 'preRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737581', 'preRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737582', 'postRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737583', 'postRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+
+INSERT INTO "public"."namespace_plugin_rel" ("id","namespace_id","plugin_id", 
"config", "sort", "enabled", "date_created", "date_updated") VALUES 
('1801816010882822189','649330b6-c2d7-4edc-be8e-8a54df9eb385','52', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
 
 INSERT INTO "public"."resource" VALUES ('1844026099075534859', 
'1346775491550474240', 'aiTokenLimiter', 'aiTokenLimiter', 
'/plug/aiTokenLimiter', 'aiTokenLimiter', 1, 0, 'pic-center', 0, 0, '', 1, 
'2022-05-25 18:02:58', '2022-05-25 18:02:58');
 INSERT INTO "public"."resource" VALUES ('1844026099075534860', 
'1844026099075534859', 'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiTokenLimiterSelector:add', 1, '2022-05-25 18:02:58', 
'2022-05-25 18:02:58');
@@ -2876,4 +2900,4 @@ INSERT INTO "public"."shenyu_dict" VALUES 
('1679002911061737495', 'aiTokenLimitT
 INSERT INTO "public"."plugin_handle" VALUES ('1899702350766538752', '51', 
'aiTokenLimitType', 'aiTokenLimitType', 3, 2, 0, '{"required":"0","rule":""}', 
'2025-03-12 06:01:49.725', '2025-03-12 06:07:49.856');
 INSERT INTO "public"."plugin_handle" VALUES ('1899702411294539776', '51', 
'timeWindowSeconds', 'timeWindowSeconds', 1, 2, 1, 
'{"required":"0","rule":""}', '2025-03-12 06:02:04.155', '2025-03-12 
06:02:04.155');
 INSERT INTO "public"."plugin_handle" VALUES ('1899702472330051584', '51', 
'keyName', 'keyName', 2, 2, 2, '{"required":"0","rule":""}', '2025-03-12 
06:02:18.707', '2025-03-12 06:02:18.707');
-INSERT INTO "public"."plugin_handle" VALUES ('1899702529972371456', '51', 
'tokenLimit', 'tokenLimit', 1, 2, 3, '{"required":"0","rule":""}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
\ No newline at end of file
+INSERT INTO "public"."plugin_handle" VALUES ('1899702529972371456', '51', 
'tokenLimit', 'tokenLimit', 1, 2, 3, '{"required":"0","rule":""}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
diff --git a/db/init/oracle/schema.sql b/db/init/oracle/schema.sql
index d83d7ed532..f462dbc517 100644
--- a/db/init/oracle/schema.sql
+++ b/db/init/oracle/schema.sql
@@ -3154,6 +3154,95 @@ VALUES ('1722804548510507047', '50', 'stream', 'stream', 
3, 1, 6, '{"defaultValu
 INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ INTO plugin_handle 
(id, plugin_id, field, label, data_type, type, sort, ext_obj, date_created, 
date_updated)
 VALUES ('1722804548510507048', '50', 'prompt', 'prompt', 2, 1, 7, 
'{"required":"0","rule":""}', to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'), to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'));
 
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642741', '1346358560427216896', '1844026099075554850', 
to_timestamp('2023-08-31 06:59:01', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 06:59:01', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642742', '1346358560427216896', '1844026099075554851', 
to_timestamp('2023-08-31 07:22:07', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:22:07', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642743', '1346358560427216896', '1844026099075554852', 
to_timestamp('2023-08-31 07:14:26', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:14:26', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642744', '1346358560427216896', '1844026099075554853', 
to_timestamp('2023-08-31 07:22:07', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:22:07', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642745', '1346358560427216896', '1844026099075554854', 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642746', '1346358560427216896', '1844026099075554855', 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642747', '1346358560427216896', '1844026099075554856', 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642748', '1346358560427216896', '1844026099075554857', 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642749', '1346358560427216896', '1844026099075554858', 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642750', '1346358560427216896', '1844026099075554859', 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled, date_created, date_updated, plugin_jar) 
+VALUES ('52', 'aiPrompt', null, 'Ai', 170, 0, to_timestamp('2023-12-20 
18:02:53', 'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2023-12-20 18:02:53', 
'YYYY-MM-DD HH24:MI:SS'), null);
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ INTO plugin_handle 
(id, plugin_id, field, label, data_type, type, sort, ext_obj, date_created, 
date_updated) 
+VALUES ('1722804548510507140', '52', 'prepend', 'prepend', 2, 3, 1, 
'{"required":"0","rule":""}', to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'), to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ INTO plugin_handle 
(id, plugin_id, field, label, data_type, type, sort, ext_obj, date_created, 
date_updated) 
+VALUES ('1722804548510507141', '52', 'preRole', 'preRole', 3, 3, 2, 
'{"required":"0","rule":""}', to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'), to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ INTO plugin_handle 
(id, plugin_id, field, label, data_type, type, sort, ext_obj, date_created, 
date_updated) 
+VALUES ('1722804548510507142', '52', 'append', 'append', 2, 3, 3, 
'{"required":"0","rule":""}', to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'), to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ INTO plugin_handle 
(id, plugin_id, field, label, data_type, type, sort, ext_obj, date_created, 
date_updated) 
+VALUES ('1722804548510507143', '52', 'postRole', 'postRole', 3, 3, 4, 
'{"required":"0","rule":""}', to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'), to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554850', '1346775491550474240', 'aiPrompt', 'aiPrompt', 
'/plug/aiPrompt', 'aiPrompt', 1, 0, 'pic-center', 0, 0, '', 1, 
to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554851', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:add', 1, to_timestamp('2022-05-25 18:02:58', 
'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554852', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:query', 1, to_timestamp('2022-05-25 18:02:58', 
'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554853', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.EDIT', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:edit', 1, to_timestamp('2022-05-25 18:02:58', 
'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554854', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:delete', 1, to_timestamp('2022-05-25 18:02:58', 
'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554855', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:add', 1, to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554856', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:query', 1, to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554857', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.EDIT', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:edit', 1, to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554858', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:delete', 1, to_timestamp('2022-05-25 18:02:58', 
'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554859', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SYNCHRONIZE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPrompt:modify', 1, to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(id)) */ INTO shenyu_dict 
(id, type, dict_code, dict_name, dict_value, desc, sort, enabled, date_created, 
date_updated) 
+VALUES ('1679002911061737580', 'preRole', 'ROLE_TYPE_SYSTEM', 'SYSTEM', 
'system', 'system', 0, 1, to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD 
HH24:MI:SS'), to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(id)) */ INTO shenyu_dict 
(id, type, dict_code, dict_name, dict_value, desc, sort, enabled, date_created, 
date_updated) 
+VALUES ('1679002911061737581', 'preRole', 'ROLE_TYPE_USER', 'USER', 'user', 
'user', 1, 1, to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(id)) */ INTO shenyu_dict 
(id, type, dict_code, dict_name, dict_value, desc, sort, enabled, date_created, 
date_updated) 
+VALUES ('1679002911061737582', 'postRole', 'ROLE_TYPE_SYSTEM', 'SYSTEM', 
'system', 'system', 0, 1, to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD 
HH24:MI:SS'), to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(id)) */ INTO shenyu_dict 
(id, type, dict_code, dict_name, dict_value, desc, sort, enabled, date_created, 
date_updated) 
+VALUES ('1679002911061737583', 'postRole', 'ROLE_TYPE_USER', 'USER', 'user', 
'user', 1, 1, to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(namespace_plugin_rel(id)) */ INTO 
namespace_plugin_rel (id, namespace_id, plugin_id, config, sort, enabled, 
date_created, date_updated) 
+VALUES ('1801816010882822189', '649330b6-c2d7-4edc-be8e-8a54df9eb385', '52', 
NULL, 171, 0, to_timestamp('2022-05-25 18:02:53', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2022-05-25 18:02:53', 'YYYY-MM-DD HH24:MI:SS'));
 
 INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status) 
 VALUES ('1844026099075534859', '1346775491550474240', 'aiTokenLimiter', 
'aiTokenLimiter', '/plug/aiTokenLimiter', 'aiTokenLimiter', 1, 0, 'pic-center', 
0, 0, '', 1);
@@ -3298,4 +3387,4 @@ INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) 
*/ INTO plugin_handle (
 VALUES ('1899702472330051584', '51', 'keyName', 'keyName', 2, 2, 2, 
'{"required":"0","rule":""}', sysdate, sysdate);
 
 INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ INTO plugin_handle 
(id, plugin_id, field, label, data_type, type, sort, ext_obj, date_created, 
date_updated)
-VALUES ('1899702529972371456', '51', 'tokenLimit', 'tokenLimit', 1, 2, 3, 
'{"required":"0","rule":""}', sysdate, sysdate);
\ No newline at end of file
+VALUES ('1899702529972371456', '51', 'tokenLimit', 'tokenLimit', 1, 2, 3, 
'{"required":"0","rule":""}', sysdate, sysdate);
diff --git a/db/init/pg/create-table.sql b/db/init/pg/create-table.sql
index 34445e6d81..dcd7f9ea65 100644
--- a/db/init/pg/create-table.sql
+++ b/db/init/pg/create-table.sql
@@ -2964,6 +2964,41 @@ INSERT INTO "public"."plugin_handle" VALUES 
('1722804548510507046', '50', 'maxTo
 INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507047', '50', 
'stream', 'stream', 3, 1, 6, '{"defaultValue":"false","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507048', '50', 
'prompt', 'prompt', 2, 1, 7, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 
+INSERT INTO "public"."permission" VALUES ('1697146860569642741', 
'1346358560427216896', '1844026099075554850', '2023-08-31 06:59:01', 
'2023-08-31 06:59:01');
+INSERT INTO "public"."permission" VALUES ('1697146860569642742', 
'1346358560427216896', '1844026099075554851', '2023-08-31 07:22:07', 
'2023-08-31 07:22:07');
+INSERT INTO "public"."permission" VALUES ('1697146860569642743', 
'1346358560427216896', '1844026099075554852', '2023-08-31 07:14:26', 
'2023-08-31 07:14:26');
+INSERT INTO "public"."permission" VALUES ('1697146860569642744', 
'1346358560427216896', '1844026099075554853', '2023-08-31 07:22:07', 
'2023-08-31 07:22:07');
+INSERT INTO "public"."permission" VALUES ('1697146860569642745', 
'1346358560427216896', '1844026099075554854', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642746', 
'1346358560427216896', '1844026099075554855', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642747', 
'1346358560427216896', '1844026099075554856', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642748', 
'1346358560427216896', '1844026099075554857', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642749', 
'1346358560427216896', '1844026099075554858', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642750', 
'1346358560427216896', '1844026099075554859', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+
+INSERT INTO "public"."plugin" VALUES ('52', 'aiPrompt', null, 'Ai', 170, 0, 
'2023-12-20 18:02:53', '2023-12-20 18:02:53', null);
+
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507140', '52', 
'prepend', 'prepend', 2, 3, 1, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507141', '52', 
'preRole', 'preRole', 3, 3, 2, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507142', '52', 
'append', 'append', 2, 3, 3, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507143', '52', 
'postRole', 'postRole', 3, 3, 4, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+
+INSERT INTO "public"."resource" VALUES ('1844026099075554850', 
'1346775491550474240', 'aiPrompt', 'aiPrompt', '/plug/aiPrompt', 'aiPrompt', 1, 
0, 'pic-center', 0, 0, '', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554851', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptSelector:add', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554852', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.QUERY', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptSelector:query', 1, '2022-05-25 18:02:58', 
'2022-05-25 18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554853', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.EDIT', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptSelector:edit', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554854', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.DELETE', '', '', '', 2, 
0, '', 1, 0, 'plugin:aiPromptSelector:delete', 1, '2022-05-25 18:02:58', 
'2022-05-25 18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554855', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.ADD', '', '', '', 2, 0, '', 
1, 0, 'plugin:aiPromptRule:add', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554856', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.QUERY', '', '', '', 2, 0, '', 
1, 0, 'plugin:aiPromptRule:query', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554857', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.EDIT', '', '', '', 2, 0, '', 
1, 0, 'plugin:aiPromptRule:edit', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554858', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.DELETE', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptRule:delete', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554859', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SYNCHRONIZE', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPrompt:modify', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737580', 'preRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737581', 'preRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737582', 'postRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737583', 'postRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+
+INSERT INTO "public"."namespace_plugin_rel" ("id","namespace_id","plugin_id", 
"config", "sort", "enabled", "date_created", "date_updated") VALUES 
('1801816010882822189','649330b6-c2d7-4edc-be8e-8a54df9eb385','52', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
 
 INSERT INTO "public"."resource" VALUES ('1844026099075534859', 
'1346775491550474240', 'aiTokenLimiter', 'aiTokenLimiter', 
'/plug/aiTokenLimiter', 'aiTokenLimiter', 1, 0, 'pic-center', 0, 0, '', 1, 
'2022-05-25 18:02:58', '2022-05-25 18:02:58');
 INSERT INTO "public"."resource" VALUES ('1844026099075534860', 
'1844026099075534859', 'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiTokenLimiterSelector:add', 1, '2022-05-25 18:02:58', 
'2022-05-25 18:02:58');
@@ -2997,4 +3032,4 @@ INSERT INTO "public"."shenyu_dict" VALUES 
('1679002911061737495', 'aiTokenLimitT
 INSERT INTO "public"."plugin_handle" VALUES ('1899702350766538752', '51', 
'aiTokenLimitType', 'aiTokenLimitType', 3, 2, 0, '{"required":"0","rule":""}', 
'2025-03-12 06:01:49.725', '2025-03-12 06:07:49.856');
 INSERT INTO "public"."plugin_handle" VALUES ('1899702411294539776', '51', 
'timeWindowSeconds', 'timeWindowSeconds', 1, 2, 1, 
'{"required":"0","rule":""}', '2025-03-12 06:02:04.155', '2025-03-12 
06:02:04.155');
 INSERT INTO "public"."plugin_handle" VALUES ('1899702472330051584', '51', 
'keyName', 'keyName', 2, 2, 2, '{"required":"0","rule":""}', '2025-03-12 
06:02:18.707', '2025-03-12 06:02:18.707');
-INSERT INTO "public"."plugin_handle" VALUES ('1899702529972371456', '51', 
'tokenLimit', 'tokenLimit', 1, 2, 3, '{"required":"0","rule":""}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
\ No newline at end of file
+INSERT INTO "public"."plugin_handle" VALUES ('1899702529972371456', '51', 
'tokenLimit', 'tokenLimit', 1, 2, 3, '{"required":"0","rule":""}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
diff --git a/db/upgrade/2.7.0-upgrade-2.7.1-mysql.sql 
b/db/upgrade/2.7.0-upgrade-2.7.1-mysql.sql
index f3fead79d1..23a5003695 100755
--- a/db/upgrade/2.7.0-upgrade-2.7.1-mysql.sql
+++ b/db/upgrade/2.7.0-upgrade-2.7.1-mysql.sql
@@ -67,6 +67,46 @@ INSERT INTO `plugin_handle` VALUES ('1722804548510507046', 
'50', 'maxTokens', 'm
 INSERT INTO `plugin_handle` VALUES ('1722804548510507047', '50', 'stream', 
'stream', 3, 1, 6, '{\"defaultValue\":\"false\",\"rule\":\"\"}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 INSERT INTO `plugin_handle` VALUES ('1722804548510507048', '50', 'prompt', 
'prompt', 2, 1, 7, '{\"required\":\"0\",\"rule\":\"\"}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 
+INSERT INTO `permission` VALUES ('1697146860569642741', '1346358560427216896', 
'1844026099075554850', '2023-08-31 06:59:01', '2023-08-31 06:59:01');
+INSERT INTO `permission` VALUES ('1697146860569642742', '1346358560427216896', 
'1844026099075554851', '2023-08-31 07:22:07', '2023-08-31 07:22:07');
+INSERT INTO `permission` VALUES ('1697146860569642743', '1346358560427216896', 
'1844026099075554852', '2023-08-31 07:14:26', '2023-08-31 07:14:26');
+INSERT INTO `permission` VALUES ('1697146860569642744', '1346358560427216896', 
'1844026099075554853', '2023-08-31 07:22:07', '2023-08-31 07:22:07');
+INSERT INTO `permission` VALUES ('1697146860569642745', '1346358560427216896', 
'1844026099075554854', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642746', '1346358560427216896', 
'1844026099075554855', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642747', '1346358560427216896', 
'1844026099075554856', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642748', '1346358560427216896', 
'1844026099075554857', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642749', '1346358560427216896', 
'1844026099075554858', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642750', '1346358560427216896', 
'1844026099075554859', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+
+
+INSERT INTO `plugin` VALUES ('52', 'aiPrompt', null, 'Ai', 170, 0, '2023-12-20 
18:02:53', '2023-12-20 18:02:53', null);
+
+
+INSERT INTO plugin_handle VALUES ('1722804548510507140', '52', 'prepend', 
'prepend', 2, 3, 1, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+INSERT INTO plugin_handle VALUES ('1722804548510507141', '52', 'preRole', 
'preRole', 3, 3, 2, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+INSERT INTO plugin_handle VALUES ('1722804548510507142', '52', 'append', 
'append', 2, 3, 3, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+INSERT INTO plugin_handle VALUES ('1722804548510507143', '52', 'postRole', 
'postRole', 3, 3, 4, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+
+
+INSERT INTO `resource` VALUES ('1844026099075554850', '1346775491550474240', 
'aiPrompt', 'aiPrompt', '/plug/aiPrompt', 'aiPrompt', 1, 0, 'pic-center', 0, 0, 
'', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554851', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:add', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554852', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:query', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554853', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.EDIT', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:edit', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554854', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:delete', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554855', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:add', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554856', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:query', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554857', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.EDIT', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:edit', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554858', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:delete', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554859', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SYNCHRONIZE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPrompt:modify', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737580', 'preRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737581', 'preRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737582', 'postRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737583', 'postRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+
+INSERT INTO `namespace_plugin_rel` (`id`,`namespace_id`,`plugin_id`, `config`, 
`sort`, `enabled`, `date_created`, `date_updated`) VALUES 
('1801816010882822189','649330b6-c2d7-4edc-be8e-8a54df9eb385','52', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
+
+
 INSERT INTO `plugin` VALUES ('51', 'aiTokenLimiter', NULL, 'Ai', 171, 0, 
'2023-12-20 18:02:53', '2023-12-20 18:02:53', null);
 
 INSERT INTO `namespace_plugin_rel` (`id`,`namespace_id`,`plugin_id`, `config`, 
`sort`, `enabled`, `date_created`, `date_updated`) VALUES 
('1801816010882822188','649330b6-c2d7-4edc-be8e-8a54df9eb385','51', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
@@ -113,4 +153,4 @@ INSERT INTO `shenyu_dict` VALUES ('1679002911061737495', 
'aiTokenLimitKey', 'COO
 INSERT INTO `plugin_handle` VALUES ('1899702350766538752', '51', 
'aiTokenLimitKey', 'aiTokenLimitKey', 3, 2, 0, 
'{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 06:01:49.725', '2025-03-12 
06:07:49.856');
 INSERT INTO `plugin_handle` VALUES ('1899702411294539776', '51', 
'timeWindowSeconds', 'timeWindowSeconds', 1, 2, 1, 
'{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 06:02:04.155', '2025-03-12 
06:02:04.155');
 INSERT INTO `plugin_handle` VALUES ('1899702472330051584', '51', 'keyName', 
'keyName', 2, 2, 2, '{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 
06:02:18.707', '2025-03-12 06:02:18.707');
-INSERT INTO `plugin_handle` VALUES ('1899702529972371456', '51', 'tokenLimit', 
'tokenLimit', 1, 2, 3, '{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
\ No newline at end of file
+INSERT INTO `plugin_handle` VALUES ('1899702529972371456', '51', 'tokenLimit', 
'tokenLimit', 1, 2, 3, '{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
diff --git a/db/upgrade/2.7.0-upgrade-2.7.1-ob.sql 
b/db/upgrade/2.7.0-upgrade-2.7.1-ob.sql
index b97d7b916c..e43cbb020e 100755
--- a/db/upgrade/2.7.0-upgrade-2.7.1-ob.sql
+++ b/db/upgrade/2.7.0-upgrade-2.7.1-ob.sql
@@ -66,6 +66,44 @@ INSERT INTO `plugin_handle` VALUES ('1722804548510507045', 
'50', 'temperature',
 INSERT INTO `plugin_handle` VALUES ('1722804548510507046', '50', 'maxTokens', 
'maxTokens', 2, 1, 5, '{\"required\":\"0\",\"rule\":\"\", 
\"placeholder\":\"optional,0,0.01~1\"}', '2024-01-02 17:20:50.233', '2024-01-02 
17:20:50.233');
 INSERT INTO `plugin_handle` VALUES ('1722804548510507047', '50', 'stream', 
'stream', 3, 1, 6, '{\"defaultValue\":\"false\",\"rule\":\"\"}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 INSERT INTO `plugin_handle` VALUES ('1722804548510507048', '50', 'prompt', 
'prompt', 2, 1, 7, '{\"required\":\"0\",\"rule\":\"\"}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO `permission` VALUES ('1697146860569642741', '1346358560427216896', 
'1844026099075554850', '2023-08-31 06:59:01', '2023-08-31 06:59:01');
+INSERT INTO `permission` VALUES ('1697146860569642742', '1346358560427216896', 
'1844026099075554851', '2023-08-31 07:22:07', '2023-08-31 07:22:07');
+INSERT INTO `permission` VALUES ('1697146860569642743', '1346358560427216896', 
'1844026099075554852', '2023-08-31 07:14:26', '2023-08-31 07:14:26');
+INSERT INTO `permission` VALUES ('1697146860569642744', '1346358560427216896', 
'1844026099075554853', '2023-08-31 07:22:07', '2023-08-31 07:22:07');
+INSERT INTO `permission` VALUES ('1697146860569642745', '1346358560427216896', 
'1844026099075554854', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642746', '1346358560427216896', 
'1844026099075554855', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642747', '1346358560427216896', 
'1844026099075554856', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642748', '1346358560427216896', 
'1844026099075554857', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642749', '1346358560427216896', 
'1844026099075554858', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+INSERT INTO `permission` VALUES ('1697146860569642750', '1346358560427216896', 
'1844026099075554859', '2023-08-31 07:18:37', '2023-08-31 07:18:37');
+
+
+INSERT INTO `plugin` VALUES ('52', 'aiPrompt', null, 'Ai', 170, 0, '2023-12-20 
18:02:53', '2023-12-20 18:02:53', null);
+
+
+INSERT INTO plugin_handle VALUES ('1722804548510507140', '52', 'prepend', 
'prepend', 2, 3, 1, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+INSERT INTO plugin_handle VALUES ('1722804548510507141', '52', 'preRole', 
'preRole', 3, 3, 2, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+INSERT INTO plugin_handle VALUES ('1722804548510507142', '52', 'append', 
'append', 2, 3, 3, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+INSERT INTO plugin_handle VALUES ('1722804548510507143', '52', 'postRole', 
'postRole', 3, 3, 4, '{"required":"0","rule":""}', '2024-01-02 17:20:50.233', 
'2024-01-02 17:20:50.233');
+
+
+INSERT INTO `resource` VALUES ('1844026099075554850', '1346775491550474240', 
'aiPrompt', 'aiPrompt', '/plug/aiPrompt', 'aiPrompt', 1, 0, 'pic-center', 0, 0, 
'', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554851', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:add', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554852', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:query', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554853', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.EDIT', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:edit', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554854', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:delete', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554855', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:add', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554856', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:query', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554857', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.EDIT', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:edit', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554858', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:delete', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO `resource` VALUES ('1844026099075554859', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SYNCHRONIZE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPrompt:modify', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737580', 'preRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737581', 'preRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737582', 'postRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO `shenyu_dict` VALUES ('1679002911061737583', 'postRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+
+INSERT INTO `namespace_plugin_rel` (`id`,`namespace_id`,`plugin_id`, `config`, 
`sort`, `enabled`, `date_created`, `date_updated`) VALUES 
('1801816010882822189','649330b6-c2d7-4edc-be8e-8a54df9eb385','52', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
 
 INSERT INTO `plugin` VALUES ('51', 'aiTokenLimiter', NULL, 'Ai', 171, 0, 
'2023-12-20 18:02:53', '2023-12-20 18:02:53', null);
 
@@ -113,4 +151,4 @@ INSERT INTO `shenyu_dict` VALUES ('1679002911061737495', 
'aiTokenLimitKey', 'COO
 INSERT INTO `plugin_handle` VALUES ('1899702350766538752', '51', 
'aiTokenLimitKey', 'aiTokenLimitKey', 3, 2, 0, 
'{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 06:01:49.725', '2025-03-12 
06:07:49.856');
 INSERT INTO `plugin_handle` VALUES ('1899702411294539776', '51', 
'timeWindowSeconds', 'timeWindowSeconds', 1, 2, 1, 
'{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 06:02:04.155', '2025-03-12 
06:02:04.155');
 INSERT INTO `plugin_handle` VALUES ('1899702472330051584', '51', 'keyName', 
'keyName', 2, 2, 2, '{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 
06:02:18.707', '2025-03-12 06:02:18.707');
-INSERT INTO `plugin_handle` VALUES ('1899702529972371456', '51', 'tokenLimit', 
'tokenLimit', 1, 2, 3, '{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
\ No newline at end of file
+INSERT INTO `plugin_handle` VALUES ('1899702529972371456', '51', 'tokenLimit', 
'tokenLimit', 1, 2, 3, '{\"required\":\"0\",\"rule\":\"\"}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
diff --git a/db/upgrade/2.7.0-upgrade-2.7.1-og.sql 
b/db/upgrade/2.7.0-upgrade-2.7.1-og.sql
index 11f8a2723d..d0b746248b 100644
--- a/db/upgrade/2.7.0-upgrade-2.7.1-og.sql
+++ b/db/upgrade/2.7.0-upgrade-2.7.1-og.sql
@@ -68,6 +68,43 @@ INSERT INTO "public"."plugin_handle" VALUES 
('1722804548510507046', '50', 'maxTo
 INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507047', '50', 
'stream', 'stream', 3, 1, 6, '{"defaultValue":"false","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507048', '50', 
'prompt', 'prompt', 2, 1, 7, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 
+
+INSERT INTO "public"."permission" VALUES ('1697146860569642741', 
'1346358560427216896', '1844026099075554850', '2023-08-31 06:59:01', 
'2023-08-31 06:59:01');
+INSERT INTO "public"."permission" VALUES ('1697146860569642742', 
'1346358560427216896', '1844026099075554851', '2023-08-31 07:22:07', 
'2023-08-31 07:22:07');
+INSERT INTO "public"."permission" VALUES ('1697146860569642743', 
'1346358560427216896', '1844026099075554852', '2023-08-31 07:14:26', 
'2023-08-31 07:14:26');
+INSERT INTO "public"."permission" VALUES ('1697146860569642744', 
'1346358560427216896', '1844026099075554853', '2023-08-31 07:22:07', 
'2023-08-31 07:22:07');
+INSERT INTO "public"."permission" VALUES ('1697146860569642745', 
'1346358560427216896', '1844026099075554854', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642746', 
'1346358560427216896', '1844026099075554855', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642747', 
'1346358560427216896', '1844026099075554856', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642748', 
'1346358560427216896', '1844026099075554857', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642749', 
'1346358560427216896', '1844026099075554858', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642750', 
'1346358560427216896', '1844026099075554859', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+
+INSERT INTO "public"."plugin" VALUES ('52', 'aiPrompt', null, 'Ai', 170, 0, 
'2023-12-20 18:02:53', '2023-12-20 18:02:53', null);
+
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507140', '52', 
'prepend', 'prepend', 2, 3, 1, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507141', '52', 
'preRole', 'preRole', 3, 3, 2, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507142', '52', 
'append', 'append', 2, 3, 3, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507143', '52', 
'postRole', 'postRole', 3, 3, 4, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+
+INSERT INTO "public"."resource" VALUES ('1844026099075554850', 
'1346775491550474240', 'aiPrompt', 'aiPrompt', '/plug/aiPrompt', 'aiPrompt', 1, 
0, 'pic-center', 0, 0, '', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554851', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptSelector:add', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554852', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.QUERY', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptSelector:query', 1, '2022-05-25 18:02:58', 
'2022-05-25 18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554853', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.EDIT', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptSelector:edit', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554854', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.DELETE', '', '', '', 2, 
0, '', 1, 0, 'plugin:aiPromptSelector:delete', 1, '2022-05-25 18:02:58', 
'2022-05-25 18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554855', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.ADD', '', '', '', 2, 0, '', 
1, 0, 'plugin:aiPromptRule:add', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554856', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.QUERY', '', '', '', 2, 0, '', 
1, 0, 'plugin:aiPromptRule:query', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554857', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.EDIT', '', '', '', 2, 0, '', 
1, 0, 'plugin:aiPromptRule:edit', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554858', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.DELETE', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptRule:delete', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554859', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SYNCHRONIZE', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPrompt:modify', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737580', 'preRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737581', 'preRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737582', 'postRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737583', 'postRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+
+INSERT INTO "public"."namespace_plugin_rel" ("id","namespace_id","plugin_id", 
"config", "sort", "enabled", "date_created", "date_updated") VALUES 
('1801816010882822189','649330b6-c2d7-4edc-be8e-8a54df9eb385','52', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
+
 INSERT INTO "public"."plugin" VALUES ('51', 'aiTokenLimiter', NULL, 'Ai', 171, 
0, '2023-12-20 18:02:53', '2023-12-20 18:02:53', null);
 
 INSERT INTO "public"."namespace_plugin_rel" VALUES 
('1801816010882822188','649330b6-c2d7-4edc-be8e-8a54df9eb385','51', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
@@ -115,4 +152,4 @@ INSERT INTO "public"."shenyu_dict" VALUES 
('1679002911061737495', 'aiTokenLimitT
 INSERT INTO "public"."plugin_handle" VALUES ('1899702350766538752', '51', 
'aiTokenLimitType', 'aiTokenLimitType', 3, 2, 0, '{"required":"0","rule":""}', 
'2025-03-12 06:01:49.725', '2025-03-12 06:07:49.856');
 INSERT INTO "public"."plugin_handle" VALUES ('1899702411294539776', '51', 
'timeWindowSeconds', 'timeWindowSeconds', 1, 2, 1, 
'{"required":"0","rule":""}', '2025-03-12 06:02:04.155', '2025-03-12 
06:02:04.155');
 INSERT INTO "public"."plugin_handle" VALUES ('1899702472330051584', '51', 
'keyName', 'keyName', 2, 2, 2, '{"required":"0","rule":""}', '2025-03-12 
06:02:18.707', '2025-03-12 06:02:18.707');
-INSERT INTO "public"."plugin_handle" VALUES ('1899702529972371456', '51', 
'tokenLimit', 'tokenLimit', 1, 2, 3, '{"required":"0","rule":""}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
\ No newline at end of file
+INSERT INTO "public"."plugin_handle" VALUES ('1899702529972371456', '51', 
'tokenLimit', 'tokenLimit', 1, 2, 3, '{"required":"0","rule":""}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
diff --git a/db/upgrade/2.7.0-upgrade-2.7.1-oracle.sql 
b/db/upgrade/2.7.0-upgrade-2.7.1-oracle.sql
index 2713bd2515..24230dcf03 100755
--- a/db/upgrade/2.7.0-upgrade-2.7.1-oracle.sql
+++ b/db/upgrade/2.7.0-upgrade-2.7.1-oracle.sql
@@ -145,6 +145,97 @@ VALUES ('1722804548510507047', '50', 'stream', 'stream', 
3, 1, 6, '{"defaultValu
 INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ INTO plugin_handle 
(id, plugin_id, field, label, data_type, type, sort, ext_obj, date_created, 
date_updated)
 VALUES ('1722804548510507048', '50', 'prompt', 'prompt', 2, 1, 7, 
'{"required":"0","rule":""}', to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'), to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'));
 
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642741', '1346358560427216896', '1844026099075554850', 
to_timestamp('2023-08-31 06:59:01', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 06:59:01', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642742', '1346358560427216896', '1844026099075554851', 
to_timestamp('2023-08-31 07:22:07', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:22:07', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642743', '1346358560427216896', '1844026099075554852', 
to_timestamp('2023-08-31 07:14:26', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:14:26', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642744', '1346358560427216896', '1844026099075554853', 
to_timestamp('2023-08-31 07:22:07', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:22:07', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642745', '1346358560427216896', '1844026099075554854', 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642746', '1346358560427216896', '1844026099075554855', 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642747', '1346358560427216896', '1844026099075554856', 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642748', '1346358560427216896', '1844026099075554857', 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642749', '1346358560427216896', '1844026099075554858', 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(permission(id)) */ INTO permission (id, 
object_id, resource_id, date_created, date_updated) 
+VALUES ('1697146860569642750', '1346358560427216896', '1844026099075554859', 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2023-08-31 07:18:37', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled, date_created, date_updated, plugin_jar) 
+VALUES ('52', 'aiPrompt', null, 'Ai', 170, 0, to_timestamp('2023-12-20 
18:02:53', 'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2023-12-20 18:02:53', 
'YYYY-MM-DD HH24:MI:SS'), null);
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ INTO plugin_handle 
(id, plugin_id, field, label, data_type, type, sort, ext_obj, date_created, 
date_updated) 
+VALUES ('1722804548510507140', '52', 'prepend', 'prepend', 2, 3, 1, 
'{"required":"0","rule":""}', to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'), to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ INTO plugin_handle 
(id, plugin_id, field, label, data_type, type, sort, ext_obj, date_created, 
date_updated) 
+VALUES ('1722804548510507141', '52', 'preRole', 'preRole', 3, 3, 2, 
'{"required":"0","rule":""}', to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'), to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ INTO plugin_handle 
(id, plugin_id, field, label, data_type, type, sort, ext_obj, date_created, 
date_updated) 
+VALUES ('1722804548510507142', '52', 'append', 'append', 2, 3, 3, 
'{"required":"0","rule":""}', to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'), to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ INTO plugin_handle 
(id, plugin_id, field, label, data_type, type, sort, ext_obj, date_created, 
date_updated) 
+VALUES ('1722804548510507143', '52', 'postRole', 'postRole', 3, 3, 4, 
'{"required":"0","rule":""}', to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'), to_timestamp('2024-01-02 17:20:50.233', 
'YYYY-MM-DD HH24:MI:SS.FF3'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554850', '1346775491550474240', 'aiPrompt', 'aiPrompt', 
'/plug/aiPrompt', 'aiPrompt', 1, 0, 'pic-center', 0, 0, '', 1, 
to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554851', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:add', 1, to_timestamp('2022-05-25 18:02:58', 
'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554852', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:query', 1, to_timestamp('2022-05-25 18:02:58', 
'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554853', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.EDIT', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:edit', 1, to_timestamp('2022-05-25 18:02:58', 
'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554854', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SELECTOR.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptSelector:delete', 1, to_timestamp('2022-05-25 18:02:58', 
'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554855', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.ADD', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:add', 1, to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554856', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.QUERY', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:query', 1, to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554857', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.EDIT', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:edit', 1, to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554858', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.RULE.DELETE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPromptRule:delete', 1, to_timestamp('2022-05-25 18:02:58', 
'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(resource(id)) */ INTO resource (id, 
parent_id, title, name, url, component, resource_type, sort, icon, is_leaf, 
is_route, perms, status, date_created, date_updated) 
+VALUES ('1844026099075554859', '1844026099075554850', 
'SHENYU.BUTTON.PLUGIN.SYNCHRONIZE', '', '', '', 2, 0, '', 1, 0, 
'plugin:aiPrompt:modify', 1, to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD 
HH24:MI:SS'), to_timestamp('2022-05-25 18:02:58', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(id)) */ INTO shenyu_dict 
(id, type, dict_code, dict_name, dict_value, desc, sort, enabled, date_created, 
date_updated) 
+VALUES ('1679002911061737580', 'preRole', 'ROLE_TYPE_SYSTEM', 'SYSTEM', 
'system', 'system', 0, 1, to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD 
HH24:MI:SS'), to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(id)) */ INTO shenyu_dict 
(id, type, dict_code, dict_name, dict_value, desc, sort, enabled, date_created, 
date_updated) 
+VALUES ('1679002911061737581', 'preRole', 'ROLE_TYPE_USER', 'USER', 'user', 
'user', 1, 1, to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(id)) */ INTO shenyu_dict 
(id, type, dict_code, dict_name, dict_value, desc, sort, enabled, date_created, 
date_updated) 
+VALUES ('1679002911061737582', 'postRole', 'ROLE_TYPE_SYSTEM', 'SYSTEM', 
'system', 'system', 0, 1, to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD 
HH24:MI:SS'), to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(id)) */ INTO shenyu_dict 
(id, type, dict_code, dict_name, dict_value, desc, sort, enabled, date_created, 
date_updated) 
+VALUES ('1679002911061737583', 'postRole', 'ROLE_TYPE_USER', 'USER', 'user', 
'user', 1, 1, to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2024-02-07 14:31:49', 'YYYY-MM-DD HH24:MI:SS'));
+
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(namespace_plugin_rel(id)) */ INTO 
namespace_plugin_rel (id, namespace_id, plugin_id, config, sort, enabled, 
date_created, date_updated) 
+VALUES ('1801816010882822189', '649330b6-c2d7-4edc-be8e-8a54df9eb385', '52', 
NULL, 171, 0, to_timestamp('2022-05-25 18:02:53', 'YYYY-MM-DD HH24:MI:SS'), 
to_timestamp('2022-05-25 18:02:53', 'YYYY-MM-DD HH24:MI:SS'));
+
 INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name, 
config, role, sort, enabled, date_created, date_updated, plugin_jar) VALUES 
('51', 'aiTokenLimiter', NULL, 'Ai', 171, 0, to_timestamp('2023-12-20 
18:02:53', 'YYYY-MM-DD HH24:MI:SS'), to_timestamp('2023-12-20 18:02:53', 
'YYYY-MM-DD HH24:MI:SS'), null);
 
 INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX (namespace_plugin_rel(id)) */ INTO 
namespace_plugin_rel (id,namespace_id,plugin_id, config, sort, enabled) VALUES 
('1801816010882822188','649330b6-c2d7-4edc-be8e-8a54df9eb385','51', NULL, 171, 
0);
@@ -265,4 +356,4 @@ INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ 
INTO plugin_handle (
 VALUES ('1899702472330051584', '51', 'keyName', 'keyName', 2, 2, 2, 
'{"required":"0","rule":""}', sysdate, sysdate);
 
 INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin_handle(id)) */ INTO plugin_handle 
(id, plugin_id, field, label, data_type, type, sort, ext_obj, date_created, 
date_updated)
-VALUES ('1899702529972371456', '51', 'tokenLimit', 'tokenLimit', 1, 2, 3, 
'{"required":"0","rule":""}', sysdate, sysdate);
\ No newline at end of file
+VALUES ('1899702529972371456', '51', 'tokenLimit', 'tokenLimit', 1, 2, 3, 
'{"required":"0","rule":""}', sysdate, sysdate);
diff --git a/db/upgrade/2.7.0-upgrade-2.7.1-pg.sql 
b/db/upgrade/2.7.0-upgrade-2.7.1-pg.sql
index bc6e842747..90494f87b7 100755
--- a/db/upgrade/2.7.0-upgrade-2.7.1-pg.sql
+++ b/db/upgrade/2.7.0-upgrade-2.7.1-pg.sql
@@ -67,6 +67,43 @@ INSERT INTO "public"."plugin_handle" VALUES 
('1722804548510507046', '50', 'maxTo
 INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507047', '50', 
'stream', 'stream', 3, 1, 6, '{"defaultValue":"false","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507048', '50', 
'prompt', 'prompt', 2, 1, 7, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
 
+
+INSERT INTO "public"."permission" VALUES ('1697146860569642741', 
'1346358560427216896', '1844026099075554850', '2023-08-31 06:59:01', 
'2023-08-31 06:59:01');
+INSERT INTO "public"."permission" VALUES ('1697146860569642742', 
'1346358560427216896', '1844026099075554851', '2023-08-31 07:22:07', 
'2023-08-31 07:22:07');
+INSERT INTO "public"."permission" VALUES ('1697146860569642743', 
'1346358560427216896', '1844026099075554852', '2023-08-31 07:14:26', 
'2023-08-31 07:14:26');
+INSERT INTO "public"."permission" VALUES ('1697146860569642744', 
'1346358560427216896', '1844026099075554853', '2023-08-31 07:22:07', 
'2023-08-31 07:22:07');
+INSERT INTO "public"."permission" VALUES ('1697146860569642745', 
'1346358560427216896', '1844026099075554854', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642746', 
'1346358560427216896', '1844026099075554855', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642747', 
'1346358560427216896', '1844026099075554856', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642748', 
'1346358560427216896', '1844026099075554857', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642749', 
'1346358560427216896', '1844026099075554858', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+INSERT INTO "public"."permission" VALUES ('1697146860569642750', 
'1346358560427216896', '1844026099075554859', '2023-08-31 07:18:37', 
'2023-08-31 07:18:37');
+
+INSERT INTO "public"."plugin" VALUES ('52', 'aiPrompt', null, 'Ai', 170, 0, 
'2023-12-20 18:02:53', '2023-12-20 18:02:53', null);
+
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507140', '52', 
'prepend', 'prepend', 2, 3, 1, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507141', '52', 
'preRole', 'preRole', 3, 3, 2, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507142', '52', 
'append', 'append', 2, 3, 3, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+INSERT INTO "public"."plugin_handle" VALUES ('1722804548510507143', '52', 
'postRole', 'postRole', 3, 3, 4, '{"required":"0","rule":""}', '2024-01-02 
17:20:50.233', '2024-01-02 17:20:50.233');
+
+INSERT INTO "public"."resource" VALUES ('1844026099075554850', 
'1346775491550474240', 'aiPrompt', 'aiPrompt', '/plug/aiPrompt', 'aiPrompt', 1, 
0, 'pic-center', 0, 0, '', 1, '2022-05-25 18:02:58', '2022-05-25 18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554851', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.ADD', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptSelector:add', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554852', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.QUERY', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptSelector:query', 1, '2022-05-25 18:02:58', 
'2022-05-25 18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554853', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.EDIT', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptSelector:edit', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554854', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SELECTOR.DELETE', '', '', '', 2, 
0, '', 1, 0, 'plugin:aiPromptSelector:delete', 1, '2022-05-25 18:02:58', 
'2022-05-25 18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554855', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.ADD', '', '', '', 2, 0, '', 
1, 0, 'plugin:aiPromptRule:add', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554856', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.QUERY', '', '', '', 2, 0, '', 
1, 0, 'plugin:aiPromptRule:query', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554857', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.EDIT', '', '', '', 2, 0, '', 
1, 0, 'plugin:aiPromptRule:edit', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554858', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.RULE.DELETE', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPromptRule:delete', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+INSERT INTO "public"."resource" VALUES ('1844026099075554859', 
'1844026099075554850', 'SHENYU.BUTTON.PLUGIN.SYNCHRONIZE', '', '', '', 2, 0, 
'', 1, 0, 'plugin:aiPrompt:modify', 1, '2022-05-25 18:02:58', '2022-05-25 
18:02:58');
+
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737580', 'preRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737581', 'preRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737582', 'postRole', 
'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1679002911061737583', 'postRole', 
'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1, '2024-02-07 14:31:49', 
'2024-02-07 14:31:49');
+
+INSERT INTO "public"."namespace_plugin_rel" ("id","namespace_id","plugin_id", 
"config", "sort", "enabled", "date_created", "date_updated") VALUES 
('1801816010882822189','649330b6-c2d7-4edc-be8e-8a54df9eb385','52', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
+
 INSERT INTO "public"."plugin" VALUES ('51', 'aiTokenLimiter', NULL, 'Ai', 171, 
0, '2023-12-20 18:02:53', '2023-12-20 18:02:53', null);
 
 INSERT INTO "public"."namespace_plugin_rel" VALUES 
('1801816010882822188','649330b6-c2d7-4edc-be8e-8a54df9eb385','51', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
@@ -113,4 +150,4 @@ INSERT INTO "public"."shenyu_dict" VALUES 
('1679002911061737495', 'aiTokenLimitT
 INSERT INTO "public"."plugin_handle" VALUES ('1899702350766538752', '51', 
'aiTokenLimitType', 'aiTokenLimitType', 3, 2, 0, '{"required":"0","rule":""}', 
'2025-03-12 06:01:49.725', '2025-03-12 06:07:49.856');
 INSERT INTO "public"."plugin_handle" VALUES ('1899702411294539776', '51', 
'timeWindowSeconds', 'timeWindowSeconds', 1, 2, 1, 
'{"required":"0","rule":""}', '2025-03-12 06:02:04.155', '2025-03-12 
06:02:04.155');
 INSERT INTO "public"."plugin_handle" VALUES ('1899702472330051584', '51', 
'keyName', 'keyName', 2, 2, 2, '{"required":"0","rule":""}', '2025-03-12 
06:02:18.707', '2025-03-12 06:02:18.707');
-INSERT INTO "public"."plugin_handle" VALUES ('1899702529972371456', '51', 
'tokenLimit', 'tokenLimit', 1, 2, 3, '{"required":"0","rule":""}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
\ No newline at end of file
+INSERT INTO "public"."plugin_handle" VALUES ('1899702529972371456', '51', 
'tokenLimit', 'tokenLimit', 1, 2, 3, '{"required":"0","rule":""}', '2025-03-12 
06:02:32.450', '2025-03-12 06:02:32.450');
diff --git a/shenyu-admin/src/main/resources/sql-script/h2/schema.sql 
b/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
index 67b4cb2ea9..dc1d7485a9 100644
--- a/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
+++ b/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
@@ -528,6 +528,10 @@ INSERT IGNORE INTO `shenyu_dict` (`id`, 
`type`,`dict_code`, `dict_name`, `dict_v
 INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`, 
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1679002911061737483', 
'provider', 'PROVIDER_TYPE_OPENAPI', 'OpenAPI', 'OpenAPI', 'OpenAPI', 3, 1);
 INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`, 
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1679002911061737484', 
'provider', 'PROVIDER_TYPE_ALIYUN', 'ALiYun', 'ALiYun', 'ALiYun', 4, 1);
 
+INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`, 
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1679002911061737580', 
'preRole', 'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1);
+INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`, 
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1679002911061737581', 
'preRole', 'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1);
+INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`, 
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1679002911061737582', 
'postRole', 'ROLE_TYPE_SYSTEM', 'SYSTEM', 'system', 'system', 0, 1);
+INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`, 
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1679002911061737583', 
'postRole', 'ROLE_TYPE_USER', 'USER', 'user', 'user', 1, 1);
 INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`, 
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1679002911061737490', 
'aiTokenLimitType', 'DEFAULT_KEY_RESOLVER', 'default', 'DEFAULT_KEY_RESOLVER', 
'Rate limit by default', 0, 1);
 INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`, 
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1679002911061737491', 
'aiTokenLimitType', 'IP_KEY_RESOLVER', 'ip', 'ip', 'Rate limit by request ip', 
1, 1);
 INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`, 
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1679002911061737492', 
'aiTokenLimitType', 'URI_KEY_RESOLVER', 'uri', 'uri', 'Rate limit by request 
uri', 2, 1);
@@ -579,6 +583,10 @@ INSERT IGNORE INTO `plugin` (`id`, `name`, `role`, `sort`, 
`config`, `enabled`)
 INSERT IGNORE INTO `plugin` (`id`, `name`, `role`, `sort`, `config`, 
`enabled`) VALUES ('44', 'basicAuth', 'Authentication', 500, 
'{"defaultHandleJson":"{\"authorization\":\"test:test123\"}"}', '0');
 INSERT IGNORE INTO `plugin` (`id`, `name`, `role`, `sort`, `config`, 
`enabled`) VALUES ('45', 'loggingRabbitMQ', 'Logging', 171, 
'{"host":"127.0.0.1","port":5672,"password":"admin","username":"admin","exchangeName":"exchange.logging.plugin","queueName":"queue.logging.plugin","routingKey":"topic.logging","virtualHost":"/","exchangeType":"direct","durable":"true","exclusive":"false","autoDelete":"false"}',
 '0');
 
+INSERT IGNORE INTO `plugin` (`id`, `name`, `role`, `sort`, `config`, 
`enabled`) VALUES ('50', 'aiProxy', 'Ai', 171, 
'{"provider":"OpenAI","baseUrl":"https://api.openai.com/v1/chat/completions","model":"gpt-4o-mini","apiKey":"your_api_key","temperature":"0.5","maxTokens":"1000","stream":"false","prompt":""}',
 '0');
+
+INSERT IGNORE INTO `plugin` (`id`, `name`, `role`, `sort`, `config`, 
`enabled`) VALUES ('52', 'aiPrompt', 'Ai', 170, null, '0');
+
 INSERT IGNORE INTO `plugin` (`id`, `name`, `role`, `sort`, `config`, 
`enabled`) VALUES ('50', 'aiProxy', 'Ai', 200, 
'{"provider":"OpenAI","baseUrl":"https://api.openai.com/v1/chat/completions","model":"gpt-4o-mini","apiKey":"your_api_key","temperature":"0.5","maxTokens":"1000","stream":"false","prompt":""}',
 '0');
 INSERT IGNORE INTO `plugin` (`id`, `name`, `role`, `sort`, `config`, 
`enabled`) VALUES ('51', 'aiStatistic', 'Ai', 171, null, '0');
 
@@ -948,6 +956,11 @@ INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1722804548510507039', '50', 'stream', 'stream', 3, 3, 7, 
'{"defaultValue":"false","rule":""}');
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1722804548510507040', '50', 'prompt', 'prompt', 2, 3, 8, 
'{"required":"0","rule":""}');
 
+INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1722804548510507140', '52', 'prepend', 'prepend', 2, 3, 1, 
'{"required":"0","rule":""}');
+INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1722804548510507141', '52', 'preRole', 'preRole', 3, 3, 2, 
'{"required":"0","rule":""}');
+INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1722804548510507142', '52', 'append', 'append', 2, 3, 3, 
'{"required":"0","rule":""}');
+INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1722804548510507143', '52', 'postRole', 'postRole', 3, 3, 4, 
'{"required":"0","rule":""}');
+
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1722804548510507049', '51', 'database', 'database', 1, 3, 2, 
'{\"required\":\"0\",\"defaultValue\":\"0\",\"rule\":\"\"}');
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1722804548510507050', '51', 'master', 'master', 2, 3, 3, 
'{\"required\":\"0\",\"rule\":\"\"}');
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1722804548510507051', '51', 'mode', 'mode', 2, 3, 4, 
'{\"required\":\"0\",\"defaultValue\":\"standalone\",\"rule\":\"\"}');
@@ -962,6 +975,7 @@ INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1899702472330051584', '51', 'keyName', 'keyName', 2, 2, 2, 
'{\"required\":\"0\",\"rule\":\"\"}');
 INSERT IGNORE INTO plugin_handle (`id`, 
`plugin_id`,`field`,`label`,`data_type`,`type`,`sort`,`ext_obj`) VALUES 
('1899702529972371456', '51', 'tokenLimit', 'tokenLimit', 1, 2, 3, 
'{\"required\":\"0\",\"rule\":\"\"}');
 
+
 /** insert resource for resource */
 INSERT IGNORE INTO `resource` (`id`, `parent_id`, `title`, `name`, `url`, 
`component`, `resource_type`, `sort`, `icon`, `is_leaf`, `is_route`, `perms`, 
`status`) 
VALUES('1346775491550474240','','SHENYU.MENU.PLUGIN.LIST','plug','/plug','PluginList','0','0','dashboard','0','0','','1');
 
@@ -1386,6 +1400,8 @@ INSERT IGNORE INTO `namespace_plugin_rel` 
(`id`,`namespace_id`,`plugin_id`, `con
 INSERT IGNORE INTO `namespace_plugin_rel` (`id`,`namespace_id`,`plugin_id`, 
`config`, `sort`, `enabled`, `date_created`, `date_updated`) VALUES 
('1801816010882822187','649330b6-c2d7-4edc-be8e-8a54df9eb385','50', 
'{"provider":"OpenAI","baseUrl":"https://api.openai.com/v1/chat/completions","model":"gpt-4o-mini","apiKey":"your_api_key","temperature":"0.5","maxTokens":"1000","stream":"false","prompt":""}',
 200, 0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
 INSERT IGNORE INTO `namespace_plugin_rel` (`id`,`namespace_id`,`plugin_id`, 
`config`, `sort`, `enabled`, `date_created`, `date_updated`) VALUES 
('1801816010882822188','649330b6-c2d7-4edc-be8e-8a54df9eb385','51', NULL, 171, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
 
+INSERT IGNORE INTO `namespace_plugin_rel` (`id`,`namespace_id`,`plugin_id`, 
`config`, `sort`, `enabled`, `date_created`, `date_updated`) VALUES 
('1801816010882822189','649330b6-c2d7-4edc-be8e-8a54df9eb385','52', NULL, 170, 
0, '2022-05-25 18:02:53.000', '2022-05-25 18:02:53.000');
+
 
 
 INSERT IGNORE INTO `resource` (`id`, `parent_id`, `title`, `name`, `url`, 
`component`, `resource_type`, `sort`, `icon`, `is_leaf`, `is_route`, `perms`, 
`status`, `date_created`, `date_updated`)
diff --git a/shenyu-bootstrap/pom.xml b/shenyu-bootstrap/pom.xml
index 6f0c242c52..73847f16ff 100644
--- a/shenyu-bootstrap/pom.xml
+++ b/shenyu-bootstrap/pom.xml
@@ -246,6 +246,14 @@
             <version>${project.version}</version>
         </dependency>
         <!--Ai proxy Plugin end-->
+        
+        <!--Ai prompt Plugin Start-->
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            
<artifactId>shenyu-spring-boot-starter-plugin-ai-prompt</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!--Ai prompt Plugin end-->
 
         <!--Ai token limiter Plugin Start-->
         <dependency>
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java 
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
index b75e179346..0e8392d8c6 100644
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
@@ -946,6 +946,11 @@ public interface Constants {
      */
     String PROMPT = "prompt";
 
+    /**
+     * The constant messages.
+     */
+    String MESSAGES = "messages";
+
     /**
      * The constant usedTokens.
      */
@@ -962,9 +967,14 @@ public interface Constants {
     String CONTENT_ENCODING = "Content-Encoding";
     
     /**
-     * The constant ai_token_statistic_key_prefix.
+     * The constant Content.
+     */
+    String CONTENT = "content";
+    
+    /**
+     * The constant ROLE.
      */
-    String AI_TOKEN_STATISTIC_KEY_PREFIX = "ai_token_statistic_";
+    String ROLE = "role";
     
     /**
      * String q.
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/plugin/AiPromptConfig.java
 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/plugin/AiPromptConfig.java
new file mode 100644
index 0000000000..589f018660
--- /dev/null
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/plugin/AiPromptConfig.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.shenyu.common.dto.convert.plugin;
+
+import java.util.Objects;
+
+/**
+ * this is Ai Prompt plugin config.
+ */
+public class AiPromptConfig {
+
+    /**
+     * prepend.
+     */
+    private String prepend;
+    
+    /**
+     * preRole.
+     */
+    private String preRole;
+    
+    /**
+     * append.
+     */
+    private String append;
+    
+    /**
+     * postRole.
+     */
+    private String postRole;
+    
+    /**
+     * get prepend.
+     *
+     * @return prepend
+     */
+    public String getPrepend() {
+        return prepend;
+    }
+    
+    /**
+     * set prepend.
+     *
+     * @param prepend prepend
+     */
+    public void setPrepend(final String prepend) {
+        this.prepend = prepend;
+    }
+    
+    /**
+     * get preRole.
+     *
+     * @return preRole
+     */
+    public String getPreRole() {
+        return preRole;
+    }
+    
+    /**
+     * set preRole.
+     *
+     * @param preRole preRole
+     */
+    public void setPreRole(final String preRole) {
+        this.preRole = preRole;
+    }
+    
+    /**
+     * get append.
+     *
+     * @return append
+     */
+    public String getAppend() {
+        return append;
+    }
+    
+    /**
+     * set append.
+     *
+     * @param append append
+     */
+    public void setAppend(final String append) {
+        this.append = append;
+    }
+    
+    /**
+     * get postRole.
+     *
+     * @return postRole
+     */
+    public String getPostRole() {
+        return postRole;
+    }
+    
+    /**
+     * set postRole.
+     *
+     * @param postRole postRole
+     */
+    public void setPostRole(final String postRole) {
+        this.postRole = postRole;
+    }
+    
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (Objects.isNull(o) || getClass() != o.getClass()) {
+            return false;
+        }
+        AiPromptConfig that = (AiPromptConfig) o;
+        return Objects.equals(prepend, that.prepend) && 
Objects.equals(preRole, that.preRole)
+                && Objects.equals(append, that.append) && 
Objects.equals(postRole, that.postRole);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(prepend, preRole, append, postRole);
+    }
+
+    @Override
+    public String toString() {
+        return "AiPromptConfig{" + "prepend='" + prepend + '\'' + ", 
preRole='" + preRole + '\'' + ", append='" + append + '\''
+                + ", postRole='" + postRole + '\'' + '}';
+    }
+}
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/plugin/AiProxyConfig.java
 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/plugin/AiProxyConfig.java
index 7fedc8881c..f057c39301 100644
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/plugin/AiProxyConfig.java
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/plugin/AiProxyConfig.java
@@ -54,11 +54,6 @@ public class AiProxyConfig {
      */
     private Integer maxTokens;
 
-    /**
-     * prompt.
-     */
-    private String prompt;
-
     /**
      * stream.
      */
@@ -172,24 +167,6 @@ public class AiProxyConfig {
         this.maxTokens = maxTokens;
     }
 
-    /**
-     * get prompt.
-     *
-     * @return prompt
-     */
-    public String getPrompt() {
-        return prompt;
-    }
-
-    /**
-     * set prompt.
-     *
-     * @param prompt prompt
-     */
-    public void setPrompt(final String prompt) {
-        this.prompt = prompt;
-    }
-
     /**
      * get stream.
      *
@@ -223,21 +200,24 @@ public class AiProxyConfig {
                 && Objects.equals(model, that.model)
                 && Objects.equals(temperature, that.temperature)
                 && Objects.equals(maxTokens, that.maxTokens)
-                && Objects.equals(prompt, that.prompt)
                 && Objects.equals(stream, that.stream);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(provider, baseUrl, apiKey, model, temperature, 
maxTokens, prompt, stream);
+        return Objects.hash(provider, baseUrl, apiKey, model, temperature, 
maxTokens, stream);
     }
 
     @Override
     public String toString() {
-        return "AiProxyHandle{" + "provider='" + provider + '\'' + "baseUrl='" 
+ baseUrl + '\'' + ", apiKey='" + apiKey
-                + '\'' + ", model='" + model
-                + '\''
-                + ", temperature=" + temperature + ", maxTokens=" + maxTokens
-                + ", prompt='" + prompt + '\'' + ", stream=" + stream + '}';
+        return "AiProxyConfig{"
+                + "provider='" + provider + '\''
+                + ", baseUrl='" + baseUrl + '\''
+                + ", apiKey='" + apiKey + '\''
+                + ", model='" + model + '\''
+                + ", temperature=" + temperature
+                + ", maxTokens=" + maxTokens
+                + ", stream=" + stream
+                + '}';
     }
 }
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/AiPromptHandle.java
 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/AiPromptHandle.java
new file mode 100644
index 0000000000..f39915eda6
--- /dev/null
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/AiPromptHandle.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.shenyu.common.dto.convert.rule;
+
+import java.util.Objects;
+
+/**
+ * this is Ai Prompt plugin selector handle.
+ */
+public class AiPromptHandle {
+
+    /**
+     * prepend.
+     */
+    private String prepend;
+    
+    /**
+     * preRole.
+     */
+    private String preRole;
+    
+    /**
+     * append.
+     */
+    private String append;
+    
+    /**
+     * postRole.
+     */
+    private String postRole;
+    
+    /**
+     * get prepend.
+     *
+     * @return prepend
+     */
+    public String getPrepend() {
+        return prepend;
+    }
+    
+    /**
+     * set prepend.
+     *
+     * @param prepend prepend
+     */
+    public void setPrepend(final String prepend) {
+        this.prepend = prepend;
+    }
+    
+    /**
+     * get preRole.
+     *
+     * @return preRole
+     */
+    public String getPreRole() {
+        return preRole;
+    }
+    
+    /**
+     * set preRole.
+     *
+     * @param preRole preRole
+     */
+    public void setPreRole(final String preRole) {
+        this.preRole = preRole;
+    }
+    
+    /**
+     * get append.
+     *
+     * @return append
+     */
+    public String getAppend() {
+        return append;
+    }
+    
+    /**
+     * set append.
+     *
+     * @param append append
+     */
+    public void setAppend(final String append) {
+        this.append = append;
+    }
+    
+    /**
+     * get postRole.
+     *
+     * @return postRole
+     */
+    public String getPostRole() {
+        return postRole;
+    }
+    
+    /**
+     * set postRole.
+     *
+     * @param postRole postRole
+     */
+    public void setPostRole(final String postRole) {
+        this.postRole = postRole;
+    }
+    
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (Objects.isNull(o) || getClass() != o.getClass()) {
+            return false;
+        }
+        AiPromptHandle that = (AiPromptHandle) o;
+        return Objects.equals(prepend, that.prepend) && 
Objects.equals(preRole, that.preRole)
+                && Objects.equals(append, that.append) && 
Objects.equals(postRole, that.postRole);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(prepend, preRole, append, postRole);
+    }
+
+    @Override
+    public String toString() {
+        return "AiPromptConfig{" + "prepend='" + prepend + '\'' + ", 
preRole='" + preRole + '\'' + ", append='" + append + '\''
+                + ", postRole='" + postRole + '\'' + '}';
+    }
+}
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/AiProxyHandle.java
 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/AiProxyHandle.java
index d6e52f0918..5ce3b7589c 100644
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/AiProxyHandle.java
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/rule/AiProxyHandle.java
@@ -56,11 +56,6 @@ public class AiProxyHandle {
      */
     private Integer maxTokens;
     
-    /**
-     * prompt.
-     */
-    private String prompt;
-    
     /**
      * stream.
      */
@@ -190,24 +185,6 @@ public class AiProxyHandle {
         this.maxTokens = maxTokens;
     }
     
-    /**
-     * get prompt.
-     *
-     * @return prompt
-     */
-    public String getPrompt() {
-        return prompt;
-    }
-    
-    /**
-     * set prompt.
-     *
-     * @param prompt prompt
-     */
-    public void setPrompt(final String prompt) {
-        this.prompt = prompt;
-    }
-    
     /**
      * get stream.
      *
@@ -241,21 +218,24 @@ public class AiProxyHandle {
                 && Objects.equals(model, that.model)
                 && Objects.equals(temperature, that.temperature)
                 && Objects.equals(maxTokens, that.maxTokens)
-                && Objects.equals(prompt, that.prompt)
                 && Objects.equals(stream, that.stream);
     }
     
     @Override
     public int hashCode() {
-        return Objects.hash(provider, baseUrl, apiKey, model, temperature, 
maxTokens, prompt, stream);
+        return Objects.hash(provider, baseUrl, apiKey, model, temperature, 
maxTokens, stream);
     }
     
     @Override
     public String toString() {
-        return "AiProxyHandle{" + "provider='" + provider + '\'' + "baseUrl='" 
+ baseUrl + '\'' + ", apiKey='" + apiKey
-                + '\'' + ", model='" + model
-                + '\''
-                + ", temperature=" + temperature + ", maxTokens=" + maxTokens
-                + ", prompt='" + prompt + '\'' + ", stream=" + stream + '}';
+        return "AiProxyHandle{"
+                + "provider='" + provider + '\''
+                + ", baseUrl='" + baseUrl + '\''
+                + ", apiKey='" + apiKey + '\''
+                + ", model='" + model + '\''
+                + ", temperature=" + temperature
+                + ", maxTokens=" + maxTokens
+                + ", stream=" + stream
+                + '}';
     }
 }
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/enums/PluginEnum.java 
b/shenyu-common/src/main/java/org/apache/shenyu/common/enums/PluginEnum.java
index eb0b434210..26caf065b1 100644
--- a/shenyu-common/src/main/java/org/apache/shenyu/common/enums/PluginEnum.java
+++ b/shenyu-common/src/main/java/org/apache/shenyu/common/enums/PluginEnum.java
@@ -142,6 +142,11 @@ public enum PluginEnum {
      */
     LOGGING_CONSOLE(160, 0, "loggingConsole"),
     
+    /**
+     * AI Prompt plugin enum.
+     */
+    AI_PROMPT(170, 0, "aiPrompt"),
+    
     /**
      * Logging RocketMQ plugin enum.
      */
diff --git a/shenyu-plugin/pom.xml b/shenyu-plugin/pom.xml
index d480f81613..5bd15e5325 100644
--- a/shenyu-plugin/pom.xml
+++ b/shenyu-plugin/pom.xml
@@ -50,6 +50,7 @@
         <module>shenyu-plugin-security</module>
         <module>shenyu-plugin-fault-tolerance</module>
         <module>shenyu-plugin-ai-proxy</module>
+        <module>shenyu-plugin-ai-prompt</module>
         <module>shenyu-plugin-ai-token-limiter</module>
     </modules>
 
diff --git a/shenyu-plugin/shenyu-plugin-ai-prompt/pom.xml 
b/shenyu-plugin/shenyu-plugin-ai-prompt/pom.xml
new file mode 100644
index 0000000000..e9a66ada67
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-ai-prompt/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <groupId>org.apache.shenyu</groupId>
+        <artifactId>shenyu-plugin</artifactId>
+        <version>2.7.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>shenyu-plugin-ai-prompt</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-plugin-base</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git 
a/shenyu-plugin/shenyu-plugin-ai-prompt/src/main/java/org/apache/shenyu/plugin/ai/prompt/AiPromptPlugin.java
 
b/shenyu-plugin/shenyu-plugin-ai-prompt/src/main/java/org/apache/shenyu/plugin/ai/prompt/AiPromptPlugin.java
new file mode 100644
index 0000000000..b46b56b83d
--- /dev/null
+++ 
b/shenyu-plugin/shenyu-plugin-ai-prompt/src/main/java/org/apache/shenyu/plugin/ai/prompt/AiPromptPlugin.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.shenyu.plugin.ai.prompt;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.shenyu.common.constant.Constants;
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.common.dto.convert.plugin.AiPromptConfig;
+import org.apache.shenyu.common.dto.convert.rule.AiPromptHandle;
+import org.apache.shenyu.common.enums.PluginEnum;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.common.utils.Singleton;
+import org.apache.shenyu.plugin.ai.prompt.handler.AiPromptPluginDataHandler;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.api.exception.ResponsiveException;
+import org.apache.shenyu.plugin.api.utils.WebFluxResultUtils;
+import org.apache.shenyu.plugin.base.AbstractShenyuPlugin;
+import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
+import org.apache.shenyu.plugin.base.utils.ServerWebExchangeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.codec.HttpMessageReader;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Ai Prompt Plugin.
+ */
+public class AiPromptPlugin extends AbstractShenyuPlugin {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(AiPromptPlugin.class);
+    
+    private final List<HttpMessageReader<?>> messageReaders;
+    
+    public AiPromptPlugin(final List<HttpMessageReader<?>> messageReaders) {
+        this.messageReaders = messageReaders;
+    }
+    
+    @Override
+    protected Mono<Void> doExecute(final ServerWebExchange exchange, final 
ShenyuPluginChain chain, final SelectorData selector, final RuleData rule) {
+        AiPromptConfig aiPromptConfig = 
Singleton.INST.get(AiPromptConfig.class);
+        if (Objects.isNull(aiPromptConfig)) {
+            aiPromptConfig = new AiPromptConfig();
+        }
+        
+        AiPromptHandle aiPromptHandle = 
AiPromptPluginDataHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(rule));
+        
+        // Create final config with selector handle taking precedence
+        if (Objects.nonNull(aiPromptHandle)) {
+            aiPromptConfig.setPreRole(aiPromptHandle.getPreRole());
+            aiPromptConfig.setPrepend(aiPromptHandle.getPrepend());
+            aiPromptConfig.setPostRole(aiPromptHandle.getPostRole());
+            aiPromptConfig.setAppend(aiPromptHandle.getAppend());
+        }
+        
+        final AiPromptConfig finalAiPromptConfig = aiPromptConfig;
+        return ServerWebExchangeUtils.rewriteRequestBody(exchange,
+                        messageReaders,
+                        originalBody -> Mono.just(decorateBody(originalBody, 
finalAiPromptConfig))
+                ).flatMap(chain::execute)
+                .onErrorResume(error -> {
+                    if (error instanceof ResponsiveException) {
+                        return 
WebFluxResultUtils.failedResult((ResponsiveException) error);
+                    }
+                    return Mono.error(error);
+                });
+        
+    }
+    
+    private String decorateBody(final String originalBody, final 
AiPromptConfig aiPromptConfig) {
+        Map<String, Object> requestBodyMap = 
GsonUtils.getInstance().convertToMap(originalBody);
+        Object rawMessages = requestBodyMap.get(Constants.MESSAGES);
+        
+        // If there is no message body, return directly
+        if (Objects.isNull(rawMessages)) {
+            return originalBody;
+        }
+        List messages = (List) rawMessages;
+        if (CollectionUtils.isEmpty(messages)) {
+            return originalBody;
+        }
+        
+        List<Object> decoratedMessages = Lists.newArrayList();
+        // If prepend in aiPromptConfig is not empty, add prepend to the front 
of message body
+        if (Objects.nonNull(aiPromptConfig.getPrepend()) && 
Objects.nonNull(aiPromptConfig.getPreRole())) {
+            // Assemble prepend content role
+            Map<String, Object> prependMap = Maps.newHashMap();
+            prependMap.put(Constants.CONTENT, aiPromptConfig.getPrepend());
+            prependMap.put(Constants.ROLE, aiPromptConfig.getPreRole());
+            decoratedMessages.add(prependMap);
+        }
+        decoratedMessages.add(messages.get(0));
+        // If append in aiPromptConfig is not empty, add append to the end of 
message body
+        if (Objects.nonNull(aiPromptConfig.getAppend()) && 
Objects.nonNull(aiPromptConfig.getPostRole())) {
+            // Assemble append content role
+            Map<String, Object> appendMap = Maps.newHashMap();
+            appendMap.put(Constants.CONTENT, aiPromptConfig.getAppend());
+            appendMap.put(Constants.ROLE, aiPromptConfig.getPostRole());
+            decoratedMessages.add(appendMap);
+        }
+        requestBodyMap.put(Constants.MESSAGES, decoratedMessages);
+        return GsonUtils.getInstance().toJson(requestBodyMap);
+    }
+    
+    @Override
+    public String named() {
+        return PluginEnum.AI_PROMPT.getName();
+    }
+
+    @Override
+    public int getOrder() {
+        return PluginEnum.AI_PROMPT.getCode();
+    }
+}
diff --git 
a/shenyu-plugin/shenyu-plugin-ai-prompt/src/main/java/org/apache/shenyu/plugin/ai/prompt/handler/AiPromptPluginDataHandler.java
 
b/shenyu-plugin/shenyu-plugin-ai-prompt/src/main/java/org/apache/shenyu/plugin/ai/prompt/handler/AiPromptPluginDataHandler.java
new file mode 100644
index 0000000000..90dcd2e354
--- /dev/null
+++ 
b/shenyu-plugin/shenyu-plugin-ai-prompt/src/main/java/org/apache/shenyu/plugin/ai/prompt/handler/AiPromptPluginDataHandler.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.shenyu.plugin.ai.prompt.handler;
+
+import org.apache.shenyu.common.dto.PluginData;
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.common.dto.convert.plugin.AiPromptConfig;
+import org.apache.shenyu.common.dto.convert.rule.AiPromptHandle;
+import org.apache.shenyu.common.enums.PluginEnum;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.common.utils.Singleton;
+import org.apache.shenyu.plugin.base.cache.CommonHandleCache;
+import org.apache.shenyu.plugin.base.handler.PluginDataHandler;
+import org.apache.shenyu.plugin.base.utils.BeanHolder;
+import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Supplier;
+
+/**
+ * The type ai prompt plugin data subscriber.
+ */
+public class AiPromptPluginDataHandler implements PluginDataHandler {
+
+    public static final Supplier<CommonHandleCache<String, AiPromptHandle>> 
CACHED_HANDLE = new BeanHolder<>(CommonHandleCache::new);
+    
+    @Override
+    public void handlerPlugin(final PluginData pluginData) {
+        if (Objects.nonNull(pluginData) && pluginData.getEnabled()) {
+            AiPromptConfig aiPromptConfig = 
GsonUtils.getInstance().fromJson(pluginData.getConfig(), AiPromptConfig.class);
+            if (Objects.isNull(aiPromptConfig)) {
+                return;
+            }
+            Singleton.INST.single(AiPromptConfig.class, aiPromptConfig);
+        }
+    }
+    
+    @Override
+    public void handlerRule(final RuleData ruleData) {
+        Optional.ofNullable(ruleData.getHandle()).ifPresent(s -> {
+            AiPromptHandle aiPromptHandle = 
GsonUtils.getInstance().fromJson(s, AiPromptHandle.class);
+            
CACHED_HANDLE.get().cachedHandle(CacheKeyUtils.INST.getKey(ruleData), 
aiPromptHandle);
+        });
+    }
+
+    @Override
+    public void removeRule(final RuleData ruleData) {
+        Optional.ofNullable(ruleData.getHandle()).ifPresent(s -> 
CACHED_HANDLE.get().removeHandle(CacheKeyUtils.INST.getKey(ruleData)));
+    }
+
+    @Override
+    public String pluginNamed() {
+        return PluginEnum.AI_PROMPT.getName();
+    }
+}
diff --git 
a/shenyu-plugin/shenyu-plugin-ai-proxy/src/main/java/org/apache/shenyu/plugin/ai/proxy/AiProxyPlugin.java
 
b/shenyu-plugin/shenyu-plugin-ai-proxy/src/main/java/org/apache/shenyu/plugin/ai/proxy/AiProxyPlugin.java
index 1db517633e..b3854adf94 100644
--- 
a/shenyu-plugin/shenyu-plugin-ai-proxy/src/main/java/org/apache/shenyu/plugin/ai/proxy/AiProxyPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-ai-proxy/src/main/java/org/apache/shenyu/plugin/ai/proxy/AiProxyPlugin.java
@@ -60,13 +60,11 @@ public class AiProxyPlugin extends AbstractShenyuPlugin {
                                    final SelectorData selector, final RuleData 
rule) {
         AiProxyConfig aiProxyConfig = Singleton.INST.get(AiProxyConfig.class);
         if (Objects.isNull(aiProxyConfig)) {
-            return chain.execute(exchange);
+            aiProxyConfig = new AiProxyConfig();
         }
         final ShenyuContext shenyuContext = 
exchange.getAttribute(Constants.CONTEXT);
         assert Objects.nonNull(shenyuContext);
         
-        String rpcType = shenyuContext.getRpcType();
-        String realUrl = shenyuContext.getRealUrl();
         // Get selector handle from cache
         AiProxyHandle selectorHandle = 
AiProxyPluginHandler.SELECTOR_CACHED_HANDLE.get()
                 .obtainHandle(CacheKeyUtils.INST.getKey(selector.getId(), 
Constants.DEFAULT_RULE));
@@ -79,10 +77,14 @@ public class AiProxyPlugin extends AbstractShenyuPlugin {
             aiProxyConfig.setModel(selectorHandle.getModel());
             aiProxyConfig.setTemperature(selectorHandle.getTemperature());
             aiProxyConfig.setMaxTokens(selectorHandle.getMaxTokens());
-            aiProxyConfig.setPrompt(selectorHandle.getPrompt());
             aiProxyConfig.setStream(selectorHandle.getStream());
         }
         
+        if (Objects.isNull(aiProxyConfig.getBaseUrl())) {
+            LOG.error("AI proxy plugin: baseUrl is null");
+            return chain.execute(exchange);
+        }
+        
         shenyuContext.setRpcType(RpcTypeEnum.AI.getName());
         exchange.getAttributes().put(Constants.CONTEXT, shenyuContext);
         
diff --git 
a/shenyu-plugin/shenyu-plugin-ai-proxy/src/main/java/org/apache/shenyu/plugin/ai/proxy/strategy/openai/OpenAI.java
 
b/shenyu-plugin/shenyu-plugin-ai-proxy/src/main/java/org/apache/shenyu/plugin/ai/proxy/strategy/openai/OpenAI.java
index 5320ebf15a..93b0797fcb 100644
--- 
a/shenyu-plugin/shenyu-plugin-ai-proxy/src/main/java/org/apache/shenyu/plugin/ai/proxy/strategy/openai/OpenAI.java
+++ 
b/shenyu-plugin/shenyu-plugin-ai-proxy/src/main/java/org/apache/shenyu/plugin/ai/proxy/strategy/openai/OpenAI.java
@@ -76,7 +76,6 @@ public class OpenAI implements AiModel {
         Map<String, Object> requestBodyMap = 
GsonUtils.getInstance().convertToMap(originalBody);
         requestBodyMap.put(Constants.MODEL, aiProxyConfig.getModel());
         requestBodyMap.put(Constants.STREAM, aiProxyConfig.getStream());
-        requestBodyMap.put(Constants.PROMPT, aiProxyConfig.getPrompt());
         return GsonUtils.getInstance().toJson(requestBodyMap);
     }
     
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/pom.xml 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/pom.xml
index 92cd7a5260..7309d13811 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/pom.xml
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/pom.xml
@@ -74,6 +74,8 @@
         <module>shenyu-spring-boot-starter-plugin-logging-huawei-lts</module>
         <module>shenyu-spring-boot-starter-plugin-basic-auth</module>
         <module>shenyu-spring-boot-starter-plugin-ai-proxy</module>
+        
+        <module>shenyu-spring-boot-starter-plugin-ai-prompt</module>
         <module>shenyu-spring-boot-starter-plugin-ai-token-limiter</module>
     </modules>
 </project>
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/pom.xml
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/pom.xml
new file mode 100644
index 0000000000..dcf5a43022
--- /dev/null
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <groupId>org.apache.shenyu</groupId>
+        <artifactId>shenyu-spring-boot-starter-plugin</artifactId>
+        <version>2.7.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>shenyu-spring-boot-starter-plugin-ai-prompt</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-plugin-ai-prompt</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/src/main/java/org/apache/shenyu/springboot/starter/plugin/ai/prompt/AiPromptPluginConfiguration.java
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/src/main/java/org/apache/shenyu/springboot/starter/plugin/ai/prompt/AiPromptPluginConfiguration.java
new file mode 100644
index 0000000000..9ae7ad8583
--- /dev/null
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/src/main/java/org/apache/shenyu/springboot/starter/plugin/ai/prompt/AiPromptPluginConfiguration.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.shenyu.springboot.starter.plugin.ai.prompt;
+
+import org.apache.shenyu.plugin.ai.prompt.AiPromptPlugin;
+import org.apache.shenyu.plugin.ai.prompt.handler.AiPromptPluginDataHandler;
+import org.apache.shenyu.plugin.api.ShenyuPlugin;
+import org.apache.shenyu.plugin.base.handler.PluginDataHandler;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.codec.ServerCodecConfigurer;
+
+/**
+ * The type ai prompt plugin configuration.
+ */
+@Configuration
+@ConditionalOnProperty(value = {"shenyu.plugins.ai.prompt.enabled"}, 
havingValue = "true", matchIfMissing = true)
+public class AiPromptPluginConfiguration {
+    
+    /**
+     * Ai proxy plugin.
+     *
+     * @param configurer the configurer
+     * @return the shenyu plugin
+     */
+    @Bean
+    public ShenyuPlugin aiPromptPlugin(final ServerCodecConfigurer configurer) 
{
+        return new AiPromptPlugin(configurer.getReaders());
+    }
+    
+    /**
+     * Ai prompt plugin handler.
+     *
+     * @return the shenyu plugin handler
+     */
+    @Bean
+    public PluginDataHandler aiPromptPluginDataHandler() {
+        return new AiPromptPluginDataHandler();
+    }
+    
+}
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/src/main/resources/META-INF/spring.factories
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000000..c0beaf6952
--- /dev/null
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.apache.shenyu.springboot.starter.plugin.ai.prompt.AiPromptPluginConfiguration
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/src/main/resources/META-INF/spring.provides
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/src/main/resources/META-INF/spring.provides
new file mode 100644
index 0000000000..eb48dee696
--- /dev/null
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/src/main/resources/META-INF/spring.provides
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+provides: shenyu-spring-boot-starter-plugin-ai-prompt
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 0000000000..ac0f5294b9
--- /dev/null
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-ai-prompt/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+org.apache.shenyu.springboot.starter.plugin.ai.prompt.AiPromptPluginConfiguration


Reply via email to