@Override
    protected Mono<Void> doExecute(final ServerWebExchange exchange, final ShenyuPluginChain chain, final SelectorData selector, final RuleData rule) {
        AiRequestTransformerConfig aiRequestTransformerConfig = Singleton.INST.get(AiRequestTransformerConfig.class);
        if (Objects.isNull(aiRequestTransformerConfig)) {
            aiRequestTransformerConfig = new AiRequestTransformerConfig();
        }

        AiRequestTransformerHandle aiRequestTransformerHandle = AiRequestTransformerPluginHandler.CACHED_HANDLE.get()
                .obtainHandle(CacheKeyUtils.INST.getKey(rule));
        ChatClient client = ChatClientCache.getInstance().getClient("default");
        // Create final config with rule handle taking precedence
        if (Objects.nonNull(aiRequestTransformerHandle)) {
            Optional.ofNullable(aiRequestTransformerHandle.getProvider()).ifPresent(aiRequestTransformerConfig::setProvider);
            Optional.ofNullable(aiRequestTransformerHandle.getBaseUrl()).ifPresent(aiRequestTransformerConfig::setBaseUrl);
            Optional.ofNullable(aiRequestTransformerHandle.getApiKey()).ifPresent(aiRequestTransformerConfig::setApiKey);
            Optional.ofNullable(aiRequestTransformerHandle.getModel()).ifPresent(aiRequestTransformerConfig::setModel);
            Optional.ofNullable(aiRequestTransformerHandle.getContent()).ifPresent(aiRequestTransformerConfig::setContent);
            client = ChatClientCache.getInstance().getClient(rule.getId());
        }

        String baseUrl = aiRequestTransformerConfig.getBaseUrl();
        String apiKey = aiRequestTransformerConfig.getApiKey();
        String provider = aiRequestTransformerConfig.getProvider();
        if (Stream.of(baseUrl, apiKey, provider).anyMatch(Objects::isNull)) {
            String missing = "";
            missing += Objects.isNull(baseUrl) ? "baseUrl, " : "";
            missing += Objects.isNull(apiKey) ? "apiKey, " : "";
            missing += Objects.isNull(provider) ? "provider, " : "";

            LOG.error("Missing configurations: {}", missing.substring(0, missing.length() - 2));
            return chain.execute(exchange);
        }

        ChatModel aiModel = aiModelFactoryRegistry
                .getFactory(AiModelProviderEnum.getByName(provider))
                .createAiModel(AiRequestTransformerPluginHandler.convertConfig(aiRequestTransformerConfig));

        if (Objects.isNull(client)) {
            client = ChatClientCache.getInstance().init(rule.getId(), aiModel);
        }

        AiRequestTransformerTemplate aiRequestTransformerTemplate = new AiRequestTransformerTemplate(aiRequestTransformerConfig.getContent(), exchange.getRequest());
        ChatClient finalClient = client;
        return aiRequestTransformerTemplate.assembleMessage()
                .flatMap(message -> Mono.fromCallable(() -> finalClient.prompt().user(message).call().content())
                        .subscribeOn(Schedulers.boundedElastic())
                        .flatMap(aiResponse -> convertHeader(exchange, aiResponse)
                                .flatMap(serverWebExchange -> convertBody(serverWebExchange, messageReaders, aiResponse))
                                    .flatMap(chain::execute)
                        )
                );

    }
this is ai request transformer plugin.
shenyu-plugin/shenyu-plugin-ai/shenyu-plugin-ai-request-transformer/src/main/java/org/apache/shenyu/plugin/ai/transformer/request/AiRequestTransformerPlugin.java