class QianfanChatModel implements ChatLanguageModel {



    private final QianfanClient client;

    private final String baseUrl;

    private final Double temperature;
    private final Double topP;
    private final String modelName;

    private final String endpoint;
    private  final Double penaltyScore;
    private final Integer maxRetries;

    private final String responseFormat;


    @Builder
    public QianfanChatModel(String baseUrl,
                            String apiKey,
                            String secretKey,
                            Double temperature,
                            Integer maxRetries,
                            Double topP,
                            String modelName,
                            String endpoint,
                            String responseFormat,
                            Double penaltyScore,
                            Boolean logRequests,
                            Boolean logResponses
                             ) {
        if (Utils.isNullOrBlank(apiKey)||Utils.isNullOrBlank(secretKey)) {
            throw new IllegalArgumentException(" api key and secret key must be defined. It can be generated here: https://console.bce.baidu.com/qianfan/ais/console/applicationConsole/application");
        }
     
        this.modelName=modelName;
        this.endpoint=Utils.isNullOrBlank(endpoint)? QianfanChatModelNameEnum.getEndpoint(modelName):endpoint;

        if (Utils.isNullOrBlank(this.endpoint) ) {
            throw new IllegalArgumentException("Qianfan is no such model name. You can see model name here: https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Nlks5zkzu");
        }

        this.baseUrl = getOrDefault(baseUrl,  "https://aip.baidubce.com");

        this.client = QianfanClient.builder()
                .baseUrl(this.baseUrl)
                .apiKey(apiKey)
                .secretKey(secretKey)
                .logRequests(logRequests)
                .logResponses(logResponses)
                .build();
        this.temperature = getOrDefault(temperature, 0.7);
        this.maxRetries = getOrDefault(maxRetries, 3);
        this.topP = topP;
        this.penaltyScore = penaltyScore;
        this.responseFormat = responseFormat;
    }


    @Override
    public Response<AiMessage> generate(List<ChatMessage> messages) {

          return  generate(messages, null,null);
    }

    @Override
    public Response<AiMessage> generate(List<ChatMessage> messages, List<ToolSpecification> toolSpecifications) {
        return generate(messages, toolSpecifications,null);
    }

    @Override
    public Response<AiMessage> generate(List<ChatMessage> messages, ToolSpecification toolSpecification) {
        throw new RuntimeException("Not supported");
    }



    private Response<AiMessage> generate(List<ChatMessage> messages,
                                         List<ToolSpecification> toolSpecifications,
                                         ToolSpecification toolThatMustBeExecuted
    ) {<FILL_FUNCTION_BODY>}


    public static QianfanChatModelBuilder builder() {
        for (QianfanChatModelBuilderFactory factory : loadFactories(QianfanChatModelBuilderFactory.class)) {
            return factory.get();
        }
        return new QianfanChatModelBuilder();
    }

    public static class QianfanChatModelBuilder {
        public QianfanChatModelBuilder() {
            // This is public so it can be extended
            // By default with Lombok it becomes package private
        }
    }
}


        ChatCompletionRequest.Builder builder = ChatCompletionRequest.builder()
                    .messages(toOpenAiMessages(messages))
                    .temperature(temperature)
                    .topP(topP)
                    .penaltyScore(penaltyScore)
                    .system(getSystemMessage(messages))
                    .responseFormat(responseFormat)
                    ;


            if (toolSpecifications != null && !toolSpecifications.isEmpty()) {
                builder.functions(toFunctions(toolSpecifications));
            }


            ChatCompletionRequest param = builder.build();


           ChatCompletionResponse response = withRetry(() -> client.chatCompletion(param, endpoint).execute(), maxRetries);


          return  Response.from(aiMessageFrom(response),
                    tokenUsageFrom(response), finishReasonFrom(response.getFinishReason()));


    
<no_super_class>