Full Code of mainpropath/AI-java for AI

master 948d411bfac1 cached
215 files
334.8 KB
96.4k tokens
644 symbols
1 requests
Download .txt
Showing preview only (443K chars total). Download the full file or copy to clipboard to get everything.
Repository: mainpropath/AI-java
Branch: master
Commit: 948d411bfac1
Files: 215
Total size: 334.8 KB

Directory structure:
gitextract_iuc1x97d/

├── README.md
├── ai-baidu/
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   └── java/
│       │       └── com/
│       │           └── ai/
│       │               └── baidu/
│       │                   ├── achieve/
│       │                   │   ├── ApiData.java
│       │                   │   ├── Configuration.java
│       │                   │   ├── defaults/
│       │                   │   │   ├── DefaultBaiduSessionFactory.java
│       │                   │   │   └── session/
│       │                   │   │       ├── DefaultAggregationSession.java
│       │                   │   │       ├── DefaultChatSession.java
│       │                   │   │       ├── DefaultEmbeddingSession.java
│       │                   │   │       ├── DefaultImageSession.java
│       │                   │   │       └── Session.java
│       │                   │   └── standard/
│       │                   │       ├── api/
│       │                   │       │   └── BaiduApiServer.java
│       │                   │       └── session/
│       │                   │           ├── AggregationSession.java
│       │                   │           ├── ChatSession.java
│       │                   │           ├── EmbeddingSession.java
│       │                   │           └── ImageSession.java
│       │                   ├── common/
│       │                   │   ├── ApiUrl.java
│       │                   │   └── Usage.java
│       │                   ├── endPoint/
│       │                   │   ├── auth/
│       │                   │   │   └── resp/
│       │                   │   │       └── AuthResponse.java
│       │                   │   ├── chat/
│       │                   │   │   ├── Message.java
│       │                   │   │   ├── SearchResult.java
│       │                   │   │   ├── req/
│       │                   │   │   │   └── ChatRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── ChatResponse.java
│       │                   │   ├── embedding/
│       │                   │   │   ├── EmbeddingData.java
│       │                   │   │   ├── req/
│       │                   │   │   │   └── EmbeddingRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── EmbeddingResponse.java
│       │                   │   └── images/
│       │                   │       ├── ImageData.java
│       │                   │       ├── req/
│       │                   │       │   └── ImageRequest.java
│       │                   │       └── resp/
│       │                   │           └── ImageResponse.java
│       │                   └── interceptor/
│       │                       └── ResponseInterceptor.java
│       └── test/
│           └── java/
│               └── com/
│                   └── ai/
│                       └── baidu/
│                           ├── ChatApiTest.java
│                           ├── EmbeddingApiTest.java
│                           └── ImageApiTest.java
├── ai-common/
│   ├── pom.xml
│   └── src/
│       └── main/
│           └── java/
│               └── com/
│                   └── ai/
│                       └── common/
│                           └── utils/
│                               ├── Exceptions.java
│                               ├── ImageUtils.java
│                               ├── JsonUtils.java
│                               └── ValidationUtils.java
├── ai-core/
│   ├── pom.xml
│   └── src/
│       └── main/
│           └── java/
│               └── com/
│                   └── ai/
│                       └── core/
│                           ├── config/
│                           │   └── BaseConfiguration.java
│                           ├── exception/
│                           │   ├── BaseException.java
│                           │   ├── Constants.java
│                           │   └── IError.java
│                           ├── factory/
│                           │   └── SessionFactory.java
│                           └── strategy/
│                               ├── KeyStrategy.java
│                               └── impl/
│                                   ├── FirstKeyStrategy.java
│                                   └── RandomKeyStrategy.java
├── ai-openai/
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   └── java/
│       │       └── com/
│       │           └── ai/
│       │               └── openai/
│       │                   ├── Product.java
│       │                   ├── Singleton.java
│       │                   ├── ThreadPrint.java
│       │                   ├── achieve/
│       │                   │   ├── Configuration.java
│       │                   │   ├── defaults/
│       │                   │   │   ├── DefaultOpenAiSessionFactory.java
│       │                   │   │   └── session/
│       │                   │   │       ├── DefaultAggregationSession.java
│       │                   │   │       ├── DefaultAudioSession.java
│       │                   │   │       ├── DefaultChatSession.java
│       │                   │   │       ├── DefaultEmbeddingSession.java
│       │                   │   │       ├── DefaultFilesSession.java
│       │                   │   │       ├── DefaultFineTuningSession.java
│       │                   │   │       ├── DefaultImageSession.java
│       │                   │   │       ├── DefaultModelSession.java
│       │                   │   │       ├── DefaultModerationSession.java
│       │                   │   │       └── Session.java
│       │                   │   └── standard/
│       │                   │       ├── api/
│       │                   │       │   └── OpenaiApiServer.java
│       │                   │       └── session/
│       │                   │           ├── AggregationSession.java
│       │                   │           ├── AudioSession.java
│       │                   │           ├── ChatSession.java
│       │                   │           ├── EmbeddingSession.java
│       │                   │           ├── FilesSession.java
│       │                   │           ├── FineTuningSession.java
│       │                   │           ├── ImageSession.java
│       │                   │           ├── ModelSession.java
│       │                   │           └── ModerationSession.java
│       │                   ├── common/
│       │                   │   ├── ApiUrl.java
│       │                   │   ├── CommonListResponse.java
│       │                   │   └── Usage.java
│       │                   ├── endPoint/
│       │                   │   ├── audio/
│       │                   │   │   ├── req/
│       │                   │   │   │   ├── SttCompletionRequest.java
│       │                   │   │   │   └── TtsCompletionRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── SttCompletionResponse.java
│       │                   │   ├── chat/
│       │                   │   │   ├── ChatChoice.java
│       │                   │   │   ├── Parameters.java
│       │                   │   │   ├── QaChoice.java
│       │                   │   │   ├── ResponseFormat.java
│       │                   │   │   ├── msg/
│       │                   │   │   │   ├── BaseMessage.java
│       │                   │   │   │   ├── Content.java
│       │                   │   │   │   ├── DefaultMessage.java
│       │                   │   │   │   ├── ImageUrl.java
│       │                   │   │   │   └── ImgMessage.java
│       │                   │   │   ├── req/
│       │                   │   │   │   ├── BaseChatCompletionRequest.java
│       │                   │   │   │   ├── DefaultChatCompletionRequest.java
│       │                   │   │   │   ├── FuncChatCompletionRequest.java
│       │                   │   │   │   ├── ImgChatCompletionRequest.java
│       │                   │   │   │   └── QaCompletionRequest.java
│       │                   │   │   ├── resp/
│       │                   │   │   │   ├── ChatCompletionResponse.java
│       │                   │   │   │   └── QaCompletionResponse.java
│       │                   │   │   └── tools/
│       │                   │   │       ├── Tool.java
│       │                   │   │       ├── ToolCall.java
│       │                   │   │       ├── ToolCallFunction.java
│       │                   │   │       └── ToolFunction.java
│       │                   │   ├── embeddings/
│       │                   │   │   ├── EmbeddingObject.java
│       │                   │   │   ├── req/
│       │                   │   │   │   └── EmbeddingCompletionRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── EmbeddingCompletionResponse.java
│       │                   │   ├── files/
│       │                   │   │   ├── FileObject.java
│       │                   │   │   └── resp/
│       │                   │   │       └── DeleteFileResponse.java
│       │                   │   ├── fineTuning/
│       │                   │   │   ├── FineTuneError.java
│       │                   │   │   ├── FineTuningEvent.java
│       │                   │   │   ├── HyperParameters.java
│       │                   │   │   ├── req/
│       │                   │   │   │   ├── FineTuningRequest.java
│       │                   │   │   │   └── ListFineTuningRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── FineTuningResponse.java
│       │                   │   ├── images/
│       │                   │   │   ├── ImageObject.java
│       │                   │   │   ├── req/
│       │                   │   │   │   ├── CreateImageRequest.java
│       │                   │   │   │   ├── ImageEditRequest.java
│       │                   │   │   │   └── ImageVariationRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── CreateImageResponse.java
│       │                   │   ├── models/
│       │                   │   │   ├── ModelObject.java
│       │                   │   │   └── resp/
│       │                   │   │       └── DeleteFineTuneModelResponse.java
│       │                   │   └── moderations/
│       │                   │       ├── Categories.java
│       │                   │       ├── CategoryScores.java
│       │                   │       ├── Result.java
│       │                   │       ├── req/
│       │                   │       │   └── ModerationRequest.java
│       │                   │       └── resp/
│       │                   │           └── ModerationResponse.java
│       │                   └── interceptor/
│       │                       ├── HeaderInterceptor.java
│       │                       └── ResponseInterceptor.java
│       └── test/
│           └── java/
│               └── com/
│                   └── ai/
│                       └── openai/
│                           ├── AudioApiTest.java
│                           ├── ChatApiTest.java
│                           ├── EmbeddingApiTest.java
│                           ├── FilesApiTest.java
│                           ├── FineTuningApiTest.java
│                           ├── ImageApiTest.java
│                           ├── ModelApiTest.java
│                           └── ModerationApiTest.java
├── ai-spark/
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   └── java/
│       │       └── com/
│       │           └── ai/
│       │               └── spark/
│       │                   ├── achieve/
│       │                   │   ├── ApiData.java
│       │                   │   ├── Configuration.java
│       │                   │   ├── defaults/
│       │                   │   │   ├── DefaultSparkSessionFactory.java
│       │                   │   │   ├── listener/
│       │                   │   │   │   ├── BaseListener.java
│       │                   │   │   │   ├── ChatListener.java
│       │                   │   │   │   ├── DocumentChatListener.java
│       │                   │   │   │   └── ImageUnderstandingListener.java
│       │                   │   │   └── session/
│       │                   │   │       ├── DefaultAggregationSession.java
│       │                   │   │       ├── DefaultAudioSession.java
│       │                   │   │       ├── DefaultChatSession.java
│       │                   │   │       ├── DefaultDocumentSession.java
│       │                   │   │       ├── DefaultEmbeddingSession.java
│       │                   │   │       ├── DefaultImageSession.java
│       │                   │   │       └── Session.java
│       │                   │   └── standard/
│       │                   │       ├── api/
│       │                   │       │   └── SparkApiServer.java
│       │                   │       └── session/
│       │                   │           ├── AggregationSession.java
│       │                   │           ├── AudioSession.java
│       │                   │           ├── ChatSession.java
│       │                   │           ├── DocumentSession.java
│       │                   │           ├── EmbeddingSession.java
│       │                   │           └── ImageSession.java
│       │                   ├── common/
│       │                   │   ├── Constants.java
│       │                   │   ├── SparkApiUrl.java
│       │                   │   ├── Usage.java
│       │                   │   ├── UsageText.java
│       │                   │   └── utils/
│       │                   │       └── AuthUtils.java
│       │                   ├── endPoint/
│       │                   │   ├── audio/
│       │                   │   │   ├── Audio.java
│       │                   │   │   ├── AudioHeader.java
│       │                   │   │   ├── AudioParameter.java
│       │                   │   │   ├── AudioPayload.java
│       │                   │   │   ├── AudioText.java
│       │                   │   │   ├── Oral.java
│       │                   │   │   ├── Pybuf.java
│       │                   │   │   ├── Tts.java
│       │                   │   │   ├── req/
│       │                   │   │   │   └── AudioRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── AudioResponse.java
│       │                   │   ├── chat/
│       │                   │   │   ├── Chat.java
│       │                   │   │   ├── ChatHeader.java
│       │                   │   │   ├── ChatParameter.java
│       │                   │   │   ├── ChatPayload.java
│       │                   │   │   ├── ChatText.java
│       │                   │   │   ├── Choice.java
│       │                   │   │   ├── Message.java
│       │                   │   │   ├── document/
│       │                   │   │   │   └── ChatExtends.java
│       │                   │   │   ├── function/
│       │                   │   │   │   ├── Function.java
│       │                   │   │   │   ├── FunctionParameter.java
│       │                   │   │   │   └── FunctionText.java
│       │                   │   │   ├── req/
│       │                   │   │   │   ├── ChatRequest.java
│       │                   │   │   │   └── DocumentChatRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       ├── ChatResponse.java
│       │                   │   │       └── DocumentChatResponse.java
│       │                   │   ├── document/
│       │                   │   │   ├── Data.java
│       │                   │   │   ├── req/
│       │                   │   │   │   └── FileUploadRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       ├── DocumentSummaryResponse.java
│       │                   │   │       └── FileUploadResponse.java
│       │                   │   ├── embedding/
│       │                   │   │   ├── Emb.java
│       │                   │   │   ├── EmbeddingHeader.java
│       │                   │   │   ├── EmbeddingMessage.java
│       │                   │   │   ├── EmbeddingParameter.java
│       │                   │   │   ├── EmbeddingPayload.java
│       │                   │   │   ├── Feature.java
│       │                   │   │   ├── req/
│       │                   │   │   │   └── EmbeddingRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── EmbeddingResponse.java
│       │                   │   └── images/
│       │                   │       ├── ImageChat.java
│       │                   │       ├── ImageHeader.java
│       │                   │       ├── ImageParameter.java
│       │                   │       ├── ImagePayload.java
│       │                   │       ├── ImageUnderstandingChat.java
│       │                   │       ├── ImageUnderstandingParameter.java
│       │                   │       ├── ImageUnderstandingPayload.java
│       │                   │       ├── req/
│       │                   │       │   ├── ImageCreateRequest.java
│       │                   │       │   └── ImageUnderstandingRequest.java
│       │                   │       └── resp/
│       │                   │           ├── ImageCreateResponse.java
│       │                   │           └── ImageUnderstandingResponse.java
│       │                   └── interceptor/
│       │                       ├── BaseUrlInterceptor.java
│       │                       └── ResponseInterceptor.java
│       └── test/
│           └── java/
│               └── com/
│                   └── ai/
│                       └── spark/
│                           ├── AudioApiTest.java
│                           ├── ChatApiTest.java
│                           ├── DocumentApiTest.java
│                           ├── EmbeddingApiTest.java
│                           └── ImageApiTest.java
├── doc/
│   └── test/
│       └── test_file_upload.txt
└── pom.xml

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
## 目录

- [**项目背景**](#项目背景)
- [**安装**](#安装)
- [**使用方式**](#使用方式)
- [**示例**](#示例)
- [**更新记录**](#更新记录)

## **项目背景**

## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=mainpropath/AI-java&type=Date)](https://star-history.com/#mainpropath/AI-java&Date)

**基于本项目的大模型框架正在火速研发当中,项目地址:[AI-SmartFuse-Framework](https://github.com/mainpropath/AI-SmartFuse-Framework)**

随着人工智能技术的飞速发展,自然语言处理在各个领域都具有广泛的应用前景。聊天机器人作为其中一种受欢迎且实用的解决方案,能够与用户进行自然对话,并提供有价值的信息和服务。

为了更好更快更方便的开发大模型应用,我们启动了一个名为AI-java的项目,专门针对Java编程语言。该SDK旨在简化与各大模型API的交互,使Java开发者可以轻松地集成大模型的功能到他们的应用程序中。

该项目的主要目标如下:

- **提供简单易用的接口:**我们致力于开发一个用户友好的SDK,提供简洁的方法和函数,使Java开发者能够轻松地与大模型进行通信。本SDK提供发送用户请求并接收生成的回复的便捷方法。
- **支持流式应答:**实时生成响应,不需要等待整个对话结束。能够快速获得反馈,更加流畅地进行对话。流式应答能够为用户提供更接近真实人类对话的体验。用户可以即时提出问题、进行追问或做出反应,而模型能够相应地作出回应和调整。
- **上下文管理:**大模型是基于上下文的,因此我们希望SDK能够支持上下文的管理,允许用户在对话过程中保持和更新上下文信息。
- **异常处理和错误处理:**我们将注重SDK的稳定性和可靠性,确保它能够有效地处理各种可能出现的错误和异常情况,并提供相应的异常处理机制。
- **示例和文档:**为了方便Java开发者快速上手使用SDK,我们将提供详细的示例代码和清晰的文档,以解释如何正确集成和使用本项目。
- **多厂商模型接入:**本项目旨在提供多个不同厂商的模型接入,大模型功能不应该局限于某一单一的模型。应当集各家之长。
- **高拓展性:**本项目所有模型功能都提供对应接口,默认实现一套接口方法,同时也可让用户根据接口实现自己的API调用方式。

## **安装**

**下载项目到本地,将项目 install 到本地 maven 仓库。**

![image-20231205204603312](doc/img/image-20231205204603312.png)

**注意,由于本项目是多模块编写,想要使用哪一个厂商的模型API,请引入对应的依赖。**

**如果使用openai相关模型功能,install 之后,在pom文件中可引入如下依赖。**

```
        <dependency>
            <groupId>com.ai</groupId>
            <artifactId>ai-openai</artifactId>
            <version>1.0</version>
        </dependency>
```

**如果使用讯飞相关模型功能,install之后,在pom文件中引入如下依赖。**

```
        <dependency>
            <groupId>com.ai</groupId>
            <artifactId>ai-spark</artifactId>
            <version>1.0</version>
        </dependency>
```

## **使用方式**

**本项目目前实现了chatGPT官方文档下 endpoints 各个板块全部的接口。正在完成讯飞星火模型相关API的编写。**

项目结构如下

```java
├─ai-common 
├─ai-openai   openai相关API功能
├─ai-spark    星火模型相关API功能
└─doc         测试相关的文件
```

**不管是使用哪一个厂商的模型API,在我们的SDK当中,使用方式都是一致的。使用方式如下:(下面是openai相关功能的使用方式)**

**具体的使用方式请参考测试类当中的测试方法。**

```java
// 工厂创建聚合的session
AggregationSession aggregationSession=factory.openAggregationSession();

// 通过聚合的session获取不同场景的会话,处理不同场景,进行解耦。
// 获取聊天会话窗口
aggregationSession.getChatSession();
// 获取文件会话窗口
aggregationSession.getFilesSession();
// 获取微调会话窗口
aggregationSession.getFineTuningSession();
// 获取图片会话窗口
aggregationSession.getImageSession();
// 获取模型会话窗口
aggregationSession.getModelSession();
// 获取音频会话窗口
aggregationSession.getAudioSession();
// 获取审核会话窗口
aggregationSession.getModerationSession();
// 获取嵌入会话窗口
aggregationSession.getEmbeddingSession();
```

## **示例**

示例相关的测试图片和语言文件在 doc/test 目录下。

openai相关功能测试如下所示,更多功能测试请参考测试类

[openai测试路径](https://github.com/mainpropath/AI-java/tree/dev/ai-openai/src/test/java/com/ai/openai)

[讯飞星火测试路径](https://github.com/mainpropath/AI-java/tree/dev/ai-spark/src/test/java/com/ai/spark)

**示例一:多轮对话**

```java
public void test_chat_completions() {
    // 创建参数,上下文对话。
    // 第一次的问题
    DefaultChatCompletionRequest defaultChatCompletionRequest = DefaultChatCompletionRequest.BuildDefaultChatCompletionRequest("1+1=");
    // 第一次的回复
    defaultChatCompletionRequest.addMessage(Constants.Role.ASSISTANT.getRoleName(), "2");
    // 第二次的问题
    defaultChatCompletionRequest.addMessage(Constants.Role.USER.getRoleName(), "2+2=");
    // 询问第二次的问题的结果
    ChatCompletionResponse chatCompletionResponse = aggregationSession.getChatSession().chatCompletions(NULL, NULL, NULL, defaultChatCompletionRequest);
    // 解析结果
    chatCompletionResponse.getChoices().forEach(e -> {
        log.info("测试结果:{}", e.getMessage());
    });
}
```

**示例二:图片创作**

```java
public void test_create_image() {
    CreateImageRequest createImageRequest = CreateImageRequest.BuildBaseCreateImageRequest("森林里有一只小熊,小熊在吃蜂蜜。");
    List<ImageObject> imageObjectList = aggregationSession.getImageSession().createImageCompletions(NULL, NULL, NULL, createImageRequest);
    log.info("测试结果:{}", imageObjectList);
}
```

**示例三:文本转语音(主要是通过回调函数获取回传的音频数据)**

```java
public void test_tts() throws InterruptedException {
    // 定义请求参数
    TtsCompletionRequest ttsCompletionRequest = TtsCompletionRequest.builder()
            .model(TtsCompletionRequest.Model.tts_1.getModuleName())// 设置使用的模型
            .input("你好,我是chatGPT")
            .voice(TtsCompletionRequest.Voice.alloy.getVoiceName())// 设置声音的样式
            .build();
    // 回传文件存放的路径
    File file = new File("doc/test/test_tts.mp3");
    // 添加回调函数,发送请求
    aggregationSession.getAudioSession().ttsCompletions(NULL, NULL, NULL, ttsCompletionRequest, new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    try (InputStream inputStream = response.body().byteStream();
                         OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) {
                        // 创建文件
                        if (!file.exists()) {
                            if (!file.getParentFile().exists()) file.getParentFile().mkdir();
                            file.createNewFile();
                        }
                        byte data[] = new byte[10240];
                        int len;
                        while ((len = inputStream.read(data, 0, 8192)) != -1) {
                            os.write(data, 0, len);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {
                    t.printStackTrace();
                }
            }
    );
    // 阻塞等待
    new CountDownLatch(1).await();
}
```

## **更新记录**

2024-01-24:完成星火模型对话、文档对话、图片生成、图片理解接口的实现。

2024-01-10:开始讯飞星火模型相关API的编写工作

2023-12-28:预启动其他模型的API编写工作

2023-12-14:修复BUG

2023-12-8:支持图片对话和函数对话

2023-12-7:优化测试用例,增加代码注释,丰富文档内容

2023-12-4:第一版SDK问世,支持官方 endpoints 下所有接口

**项目长期维护,欢迎向本项目提需求,欢迎star~~~**


================================================
FILE: ai-baidu/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>AI-java</artifactId>
        <groupId>com.ai</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ai-baidu</artifactId>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>4.13.2</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.ai</groupId>
            <artifactId>ai-common</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>com.ai</groupId>
            <artifactId>ai-core</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/ApiData.java
================================================
package com.ai.baidu.achieve;


import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 记录用户API信息
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ApiData {

    private String appId;
    private String apiKey;
    private String secretKey;
    private String accessToken;

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/Configuration.java
================================================
package com.ai.baidu.achieve;

import com.ai.baidu.achieve.standard.api.BaiduApiServer;
import com.ai.core.config.BaseConfiguration;
import lombok.*;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSources;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @Description: baidu 相关配置信息
 **/
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class Configuration extends BaseConfiguration {

    /**
     * api 服务提供者
     */
    private BaiduApiServer baiduApiServer;

    /**
     * api Key 集合
     */
    @NotNull
    private List<ApiData> keyList;

    public ApiData getSystemApiData() {
        return (ApiData) this.getKeyStrategy().apply(keyList);
    }

    public EventSource.Factory createRequestFactory() {
        return EventSources.createFactory(this.getOkHttpClient());
    }

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/DefaultBaiduSessionFactory.java
================================================
package com.ai.baidu.achieve.defaults;

import com.ai.baidu.achieve.Configuration;
import com.ai.baidu.achieve.defaults.session.DefaultAggregationSession;
import com.ai.baidu.achieve.standard.api.BaiduApiServer;
import com.ai.baidu.achieve.standard.session.AggregationSession;
import com.ai.baidu.interceptor.ResponseInterceptor;
import com.ai.core.factory.SessionFactory;
import lombok.AllArgsConstructor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;

import java.util.concurrent.TimeUnit;

/**
 * @Description: baidu API Factory 会话工厂
 **/
@AllArgsConstructor
public class DefaultBaiduSessionFactory implements SessionFactory<AggregationSession, BaiduApiServer> {

    private final Configuration configuration;

    @Override
    public OkHttpClient createHttpClient() {
        // 1. 日志配置
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.NONE);
        // 2. 开启 Http 客户端
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .addInterceptor(httpLoggingInterceptor)
                .addInterceptor(new ResponseInterceptor())
                .connectTimeout(450, TimeUnit.SECONDS)
                .writeTimeout(450, TimeUnit.SECONDS)
                .readTimeout(450, TimeUnit.SECONDS);
        // 3. 检查是否需要代理
        if (configuration.getProxy() != null) {
            builder.proxy(configuration.getProxy());
        }
        return builder.build();
    }

    @Override
    public BaiduApiServer createApiServer(OkHttpClient okHttpClient) {
        return new Retrofit.Builder()
                .baseUrl(configuration.getApiHost())
                .client(okHttpClient)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(JacksonConverterFactory.create())
                .build().create(BaiduApiServer.class);
    }

    @Override
    public AggregationSession openAggregationSession() {
        OkHttpClient okHttpClient = createHttpClient();
        configuration.setOkHttpClient(okHttpClient);
        configuration.setBaiduApiServer(createApiServer(okHttpClient));
        return new DefaultAggregationSession(configuration);
    }

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/DefaultAggregationSession.java
================================================
package com.ai.baidu.achieve.defaults.session;

import com.ai.baidu.achieve.Configuration;
import com.ai.baidu.achieve.standard.session.AggregationSession;
import com.ai.baidu.achieve.standard.session.ChatSession;
import com.ai.baidu.achieve.standard.session.EmbeddingSession;
import com.ai.baidu.achieve.standard.session.ImageSession;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;

/**
 * @Description: 聚合各个类型的session
 **/
public class DefaultAggregationSession implements AggregationSession {

    private Configuration configuration;

    private volatile ChatSession chatSession;

    private volatile EmbeddingSession embeddingSession;

    private volatile ImageSession imageSession;

    public DefaultAggregationSession(Configuration configuration) {
        this.configuration = ensureNotNull(configuration, "configuration");
    }

    @Override
    public ChatSession getChatSession() {
        if (chatSession == null) {
            synchronized (this) {
                if (chatSession == null) {
                    chatSession = new DefaultChatSession(configuration);
                }
            }
        }
        return chatSession;
    }

    @Override
    public EmbeddingSession getEmbeddingSession() {
        if (embeddingSession == null) {
            synchronized (this) {
                if (embeddingSession == null) {
                    embeddingSession = new DefaultEmbeddingSession(configuration);
                }
            }
        }
        return embeddingSession;
    }

    @Override
    public ImageSession getImageSession() {
        if (imageSession == null) {
            synchronized (this) {
                if (imageSession == null) {
                    imageSession = new DefaultImageSession(configuration);
                }
            }
        }
        return imageSession;
    }

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/DefaultChatSession.java
================================================
package com.ai.baidu.achieve.defaults.session;

import cn.hutool.http.ContentType;
import com.ai.baidu.achieve.Configuration;
import com.ai.baidu.achieve.standard.session.ChatSession;
import com.ai.baidu.common.ApiUrl;
import com.ai.baidu.endPoint.chat.req.ChatRequest;
import com.ai.baidu.endPoint.chat.resp.ChatResponse;
import com.ai.common.utils.JsonUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;

/**
 * @description baidu 对话类会话
 */
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class DefaultChatSession extends Session implements ChatSession {

    /**
     * 工厂事件
     */
    private EventSource.Factory factory;

    public DefaultChatSession(Configuration configuration) {
        this.setConfiguration(ensureNotNull(configuration, "configuration"));
        this.setBaiduApiServer(ensureNotNull(configuration.getBaiduApiServer(), "baiduApiServer"));
        this.factory = ensureNotNull(configuration.createRequestFactory(), "requestFactory");
    }

    @Override
    public ChatResponse chat(String accessToken, ChatRequest chatRequest) {
        // 检查一下是否为空,为空根据设置的 keyStrategy 获取一个用户设置的 key
        return this.getBaiduApiServer().chat(checkAccessToken(accessToken), chatRequest).blockingGet();
    }

    @Override
    public EventSource chat(String accessToken, ChatRequest chatRequest, EventSourceListener eventSourceListener) {
        // 将 accessToken 设置到请求路径上
        HttpUrl.Builder urlBuilder = HttpUrl.parse(this.getConfiguration().getApiHost().concat(ApiUrl.ERNIE_Bot_4_0.getUrl())).newBuilder();
        urlBuilder.addQueryParameter("access_token", checkAccessToken(accessToken));
        // 发起请求
        Request request = new Request.Builder()
                .url(urlBuilder.build().toString())
                .post(RequestBody.create(MediaType.parse(ContentType.JSON.getValue()), JsonUtils.toJson(chatRequest)))
                .build();
        return factory.newEventSource(request, eventSourceListener);
    }
}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/DefaultEmbeddingSession.java
================================================
package com.ai.baidu.achieve.defaults.session;

import com.ai.baidu.achieve.Configuration;
import com.ai.baidu.achieve.standard.session.EmbeddingSession;
import com.ai.baidu.endPoint.embedding.EmbeddingData;
import com.ai.baidu.endPoint.embedding.req.EmbeddingRequest;
import com.ai.baidu.endPoint.embedding.resp.EmbeddingResponse;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.util.List;
import java.util.stream.IntStream;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;

/**
 * @Description: 百度嵌入操作
 **/
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class DefaultEmbeddingSession extends Session implements EmbeddingSession {

    public DefaultEmbeddingSession(Configuration configuration) {
        this.setConfiguration(ensureNotNull(configuration, "configuration"));
        this.setBaiduApiServer(ensureNotNull(configuration.getBaiduApiServer(), "baiduApiServer"));
    }

    @Override
    public EmbeddingResponse embedding(String accessToken, EmbeddingRequest embeddingRequest) {
        EmbeddingResponse embeddingResponse = this.getBaiduApiServer().embedding(checkAccessToken(accessToken), embeddingRequest).blockingGet();
        List<EmbeddingData> data = embeddingResponse.getData();
        List<String> input = embeddingRequest.getInput();
        IntStream.range(0, Math.min(data.size(), input.size()))
                .forEach(i -> data.get(i).setContent(input.get(i)));
        return embeddingResponse;
    }

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/DefaultImageSession.java
================================================
package com.ai.baidu.achieve.defaults.session;

import com.ai.baidu.achieve.Configuration;
import com.ai.baidu.achieve.standard.session.ImageSession;
import com.ai.baidu.endPoint.images.req.ImageRequest;
import com.ai.baidu.endPoint.images.resp.ImageResponse;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;

/**
 * @Description: 图像生成
 **/
public class DefaultImageSession extends Session implements ImageSession {

    public DefaultImageSession(Configuration configuration) {
        this.setConfiguration(ensureNotNull(configuration, "configuration"));
        this.setBaiduApiServer(ensureNotNull(configuration.getBaiduApiServer(), "baiduApiServer"));
    }

    @Override
    public ImageResponse text2image(String accessToken, ImageRequest imageRequest) {
        String s = checkAccessToken(accessToken);
        return this.getBaiduApiServer().text2image(s, imageRequest).blockingGet();
    }
}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/Session.java
================================================
package com.ai.baidu.achieve.defaults.session;

import cn.hutool.core.util.StrUtil;
import com.ai.baidu.achieve.ApiData;
import com.ai.baidu.achieve.Configuration;
import com.ai.baidu.achieve.standard.api.BaiduApiServer;
import lombok.Data;


@Data
public class Session {

    /**
     * 配置信息
     */
    private Configuration configuration;
    /**
     * OpenAI 接口
     */
    private BaiduApiServer baiduApiServer;

    public String checkAccessToken(String accessToken) {
        if (StrUtil.isEmpty(accessToken)) {
            // 先随机获取一个apidata,看是否设置了accessToken,如果没有设置,获取token设置进去,然后返回。
            ApiData systemApiData = configuration.getSystemApiData();
            if (StrUtil.isNotEmpty(systemApiData.getAccessToken())) {
                return systemApiData.getAccessToken();
            }
            accessToken = baiduApiServer.getAccessToken(systemApiData.getApiKey(), systemApiData.getSecretKey());
            systemApiData.setAccessToken(accessToken);
        }
        return accessToken;
    }


}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/standard/api/BaiduApiServer.java
================================================
package com.ai.baidu.achieve.standard.api;

import com.ai.baidu.endPoint.auth.resp.AuthResponse;
import com.ai.baidu.endPoint.chat.req.ChatRequest;
import com.ai.baidu.endPoint.chat.resp.ChatResponse;
import com.ai.baidu.endPoint.embedding.req.EmbeddingRequest;
import com.ai.baidu.endPoint.embedding.resp.EmbeddingResponse;
import com.ai.baidu.endPoint.images.req.ImageRequest;
import com.ai.baidu.endPoint.images.resp.ImageResponse;
import io.reactivex.Single;
import retrofit2.http.Body;
import retrofit2.http.POST;
import retrofit2.http.Query;

/**
 * @Description: baidu API接口
 **/
public interface BaiduApiServer {

    /**
     * 鉴权接口
     *
     * @param grantType 类型
     * @param apiKey    百度千帆大模型平台 apiKey
     * @param secretKey 百度千帆大模型平台 secretKey
     * @return 返回参数
     */
    @POST("/oauth/2.0/token")
    Single<AuthResponse> auth(@Query("grant_type") String grantType, @Query("client_id") String apiKey, @Query("client_secret") String secretKey);

    /**
     * 获取鉴权的 accessToken
     *
     * @param apiKey    百度千帆大模型平台 apiKey
     * @param secretKey 百度千帆大模型平台 secretKey
     * @return 鉴权的 accessToken
     */
    default String getAccessToken(String apiKey, String secretKey) {
        return getAccessToken("client_credentials", apiKey, secretKey);
    }

    /**
     * 获取鉴权的 accessToken
     *
     * @param grantType 类型
     * @param apiKey    百度千帆大模型平台 apiKey
     * @param secretKey 百度千帆大模型平台 secretKey
     * @return 鉴权的 accessToken
     */
    default String getAccessToken(String grantType, String apiKey, String secretKey) {
        return this.auth(grantType, apiKey, secretKey).blockingGet().getAccessToken();
    }

    /**
     * 聊天接口
     *
     * @param accessToken 鉴权的 accessToken
     * @param chatRequest 请求参数
     * @return 返回数据
     */
    @POST("/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro")
    Single<ChatResponse> chat(@Query("access_token") String accessToken, @Body ChatRequest chatRequest);

    /**
     * embedding 接口
     *
     * @param accessToken      鉴权的 accessToken
     * @param embeddingRequest 请求参数
     * @return 返回数据
     */
    @POST("/rpc/2.0/ai_custom/v1/wenxinworkshop/embeddings/embedding-v1")
    Single<EmbeddingResponse> embedding(@Query("access_token") String accessToken, @Body EmbeddingRequest embeddingRequest);

    /**
     * 文生图接口
     *
     * @param accessToken  鉴权的 accessToken
     * @param imageRequest 请求参数
     * @return 返回数据
     */
    @POST("/rpc/2.0/ai_custom/v1/wenxinworkshop/text2image/sd_xl")
    Single<ImageResponse> text2image(@Query("access_token") String accessToken, @Body ImageRequest imageRequest);

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/standard/session/AggregationSession.java
================================================
package com.ai.baidu.achieve.standard.session;

/**
 * @Description: 聚合各大场景的session
 **/
public interface AggregationSession {

    /**
     * 获取对话会话窗口
     */
    ChatSession getChatSession();

    /**
     * 获取嵌入会话窗口
     */
    EmbeddingSession getEmbeddingSession();

    /**
     * 获取文生图会话窗口
     */
    ImageSession getImageSession();

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/standard/session/ChatSession.java
================================================
package com.ai.baidu.achieve.standard.session;

import com.ai.baidu.endPoint.chat.req.ChatRequest;
import com.ai.baidu.endPoint.chat.resp.ChatResponse;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;

/**
 * @Description: baidu 聊天会话窗口
 **/
public interface ChatSession {

    default ChatResponse chat(ChatRequest chatRequest) {
        return chat(null, chatRequest);
    }

    /**
     * 聊天接口,如果传入的 accessToken 为空,会自动根据用户设置的 key 按照 key 的获取策略进行自动鉴权。
     *
     * @param accessToken 鉴权的 accessToken
     * @param chatRequest 请求参数
     * @return 返回参数
     */
    ChatResponse chat(String accessToken, ChatRequest chatRequest);

    default EventSource chat(ChatRequest chatRequest, EventSourceListener eventSourceListener) {
        return chat(null, chatRequest, eventSourceListener);
    }

    /**
     * 聊天接口流式返回
     *
     * @param accessToken         鉴权的 accessToken
     * @param chatRequest         请求参数
     * @param eventSourceListener 事件监听者
     * @return 事件源
     */
    EventSource chat(String accessToken, ChatRequest chatRequest, EventSourceListener eventSourceListener);

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/standard/session/EmbeddingSession.java
================================================
package com.ai.baidu.achieve.standard.session;

import com.ai.baidu.endPoint.embedding.req.EmbeddingRequest;
import com.ai.baidu.endPoint.embedding.resp.EmbeddingResponse;

/**
 * @Description: 嵌入会话窗口
 **/
public interface EmbeddingSession {

    default EmbeddingResponse embedding(EmbeddingRequest embeddingRequest) {
        return embedding(null, embeddingRequest);
    }

    /**
     * 嵌入
     *
     * @param accessToken      鉴权的 accessToken
     * @param embeddingRequest 请求参数
     * @return 请求结果
     */
    EmbeddingResponse embedding(String accessToken, EmbeddingRequest embeddingRequest);

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/standard/session/ImageSession.java
================================================
package com.ai.baidu.achieve.standard.session;

import com.ai.baidu.endPoint.images.req.ImageRequest;
import com.ai.baidu.endPoint.images.resp.ImageResponse;

/**
 * @Description: 图片会话窗口
 **/
public interface ImageSession {

    /**
     * 文生图接口
     *
     * @param accessToken  鉴权的 accessToken
     * @param imageRequest 请求参数
     * @return 请求结果
     */
    ImageResponse text2image(String accessToken, ImageRequest imageRequest);

    default ImageResponse text2image(ImageRequest imageRequest) {
        return text2image(null, imageRequest);
    }

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/common/ApiUrl.java
================================================
package com.ai.baidu.common;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * 各接口API路径
 */
@Getter
@AllArgsConstructor
public enum ApiUrl {

    ERNIE_Bot_4_0("/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro"),
    ;

    private String url;
}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/common/Usage.java
================================================
package com.ai.baidu.common;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Usage {

    /**
     * 问题tokens数
     */
    @JsonProperty("prompt_tokens")
    private Integer promptTokens;

    /**
     * 回答tokens数
     */
    @JsonProperty("completion_tokens")
    private Integer completionTokens;

    /**
     * tokens总数
     */
    @JsonProperty("total_tokens")
    private Integer totalTokens;

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/auth/resp/AuthResponse.java
================================================
package com.ai.baidu.endPoint.auth.resp;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AuthResponse {

    @JsonProperty("refresh_token")
    private String refreshToken;

    /**
     * 有效期,Access Token的有效期。
     * 说明:单位是秒,有效期30天
     */
    @JsonProperty("expires_in")
    private Integer expiresIn;

    @JsonProperty("session_key")
    private String sessionKey;

    /**
     * 访问凭证
     */
    @JsonProperty("access_token")
    private String accessToken;

    private String scope;

    @JsonProperty("session_secret")
    private String sessionSecret;

    /**
     * 错误码
     * 说明:响应失败时返回该字段,成功时不返回
     */
    private String error;

    /**
     * 错误描述信息,帮助理解和解决发生的错误
     * 说明:响应失败时返回该字段,成功时不返回
     */
    @JsonProperty("error_description")
    private String errorDescription;

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/chat/Message.java
================================================
package com.ai.baidu.endPoint.chat;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.*;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Message {

    /**
     * 当前支持以下:
     * user: 表示用户
     * assistant: 表示对话助手
     */
    private String role;

    /**
     * 对话内容
     */
    private String content;

    /**
     * message作者
     */
    private String name;

    public static Message baseBuild(Role role, String content) {
        return Message.builder().role(role.getRoleName()).content(content).build();
    }

    @Getter
    @AllArgsConstructor
    public enum Role {

        USER("user"),
        ASSISTANT("assistant"),
        ;

        private String RoleName;
    }

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/chat/SearchResult.java
================================================
package com.ai.baidu.endPoint.chat;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SearchResult {

    /**
     * 序号
     */
    private Integer index;

    /**
     * 搜索结果URL
     */
    private String url;

    /**
     * 搜索结果标题
     */
    private String title;

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/chat/req/ChatRequest.java
================================================
package com.ai.baidu.endPoint.chat.req;

import com.ai.baidu.endPoint.chat.Message;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 对话聊天参数,官方文档链接:https://cloud.baidu.com/doc/WENXINWORKSHOP/s/clntwmv7t#body%E5%8F%82%E6%95%B0
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ChatRequest implements Serializable {

    /**
     * 必传
     * (1)messages成员不能为空,1个成员表示单轮对话,多个成员表示多轮对话,例如:
     * 3个成员示例,"messages": [ {"role": "user","content": "你好"},{"role":"assistant","content":"需要什么帮助"},{"role":"user","content":"自我介绍下"}]
     * (2)最后一个message为当前请求的信息,前面的message为历史对话信息
     * (3)成员数目必须为奇数,成员中message的role值说明如下:奇数位messsage的role值必须为user,偶数位message的role值为assistant
     * (4)message中的content总长度和system字段总内容不能超过20000个字符,且不能超过5120 tokens
     */
    private List<Message> messages;

    /**
     * (1)较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定
     * (2)默认0.8,范围 (0, 1.0],不能为0
     */
    private Double temperature;

    /**
     * (1)影响输出文本的多样性,取值越大,生成文本的多样性越强
     * (2)默认0.8,取值范围 [0, 1.0]
     */
    @JsonProperty("top_p")
    private Double topP;

    /**
     * 通过对已生成的token增加惩罚,减少重复生成的现象。说明:
     * (1)值越大表示惩罚越大
     * (2)默认1.0,取值范围:[1.0, 2.0]
     */
    @JsonProperty("penalty_score")
    private Double penaltyScore;

    /**
     * 是否以流式接口的形式返回数据,默认false
     */
    private Boolean stream;

    /**
     * 模型人设,主要用于人设设定,例如,你是xxx公司制作的AI助手,说明:
     * (1)长度限制,最后一个message的content长度(即此轮对话的问题)和system字段总内容不能超过20000个字符,且不能超过5120 tokens
     */
    private String system;

    /**
     * 生成停止标识,当模型生成结果以stop中某个元素结尾时,停止文本生成。说明:
     * (1)每个元素长度不超过20字符
     * (2)最多4个元素
     */
    private List<String> stop;

    /**
     * 否强制关闭实时搜索功能,默认false,表示不关闭
     */
    @JsonProperty("disable_search")
    private Boolean disableSearch;

    /**
     * 是否开启上角标返回,说明:
     * (1)开启后,有概率触发搜索溯源信息search_info,search_info内容见响应参数介绍
     * (2)默认false,不开启
     */
    @JsonProperty("enable_citation")
    private Boolean enableCitation;

    /**
     * 指定模型最大输出token数,范围[2, 2048]
     */
    @JsonProperty("max_output_tokens")
    private Integer maxOutputTokens;

    /**
     * 指定响应内容的格式,说明:
     * (1)可选值:
     * json_object:以json格式返回,可能出现不满足效果情况
     * text:以文本格式返回
     * (2)如果不填写参数response_format值,默认为text
     */
    @JsonProperty("response_format")
    private String responseFormat;

    /**
     * 表示最终用户的唯一标识符
     */
    @JsonProperty("user_id")
    private String userId;

    public static ChatRequest baseBuild(Message.Role role, String content) {
        return ChatRequest.builder()
                .messages(new ArrayList<>(Arrays.asList(Message.baseBuild(role, content))))
                .build();
    }

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/chat/resp/ChatResponse.java
================================================
package com.ai.baidu.endPoint.chat.resp;

import com.ai.baidu.common.Usage;
import com.ai.baidu.endPoint.chat.SearchResult;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ChatResponse implements Serializable {

    /**
     * 本轮对话的id
     */
    private String id;

    /**
     * 回包类型
     * chat.completion:多轮对话返回
     */
    private String Object;

    /**
     * 时间戳
     */
    private Integer created;

    /**
     * 表示当前子句的序号。只有在流式接口模式下会返回该字段
     */
    @JsonProperty("sentence_id")
    private Integer sentenceId;

    /**
     * 表示当前子句是否是最后一句。只有在流式接口模式下会返回该字段
     */
    @JsonProperty("is_end")
    private Boolean isEnd;

    /**
     * 当前生成的结果是否被截断
     */
    @JsonProperty("is_truncated")
    private Boolean isTruncated;

    /**
     * 输出内容标识,说明:
     * · normal:输出内容完全由大模型生成,未触发截断、替换
     * · stop:输出结果命中入参stop中指定的字段后被截断
     * · length:达到了最大的token数,根据EB返回结果is_truncated来截断
     * · content_filter:输出内容被截断、兜底、替换为**等
     */
    @JsonProperty("finish_reason")
    private String finishReason;

    /**
     * 搜索数据,当请求参数enable_citation为true并且触发搜索时,会返回该字段
     */
    @JsonProperty("search_info")
    private List<SearchResult> searchInfo;

    /**
     * 对话返回结果
     */
    private String result;

    /**
     * 表示用户输入是否存在安全,是否关闭当前会话,清理历史会话信息
     * true:是,表示用户输入存在安全风险,建议关闭当前会话,清理历史会话信息
     * false:否,表示用户输入无安全风险
     */
    @JsonProperty("need_clear_history")
    private Boolean needClearHistory;

    /**
     * 说明:
     * 0:正常返回
     * 其他:非正常
     */
    private Integer flag;

    /**
     * 当need_clear_history为true时,此字段会告知第几轮对话有敏感信息,如果是当前问题,ban_round=-1
     */
    @JsonProperty("ban_round")
    private Integer banRound;

    /**
     * token统计信息
     */
    private Usage usage;


}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/embedding/EmbeddingData.java
================================================
package com.ai.baidu.endPoint.embedding;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class EmbeddingData {

    /**
     * 固定值"embedding"
     */
    private String object;

    /**
     * embedding 内容
     */
    private double[] embedding;

    /**
     * 序号
     */
    private Integer index;

    /**
     * 原文
     */
    @JsonIgnore
    private String content;

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/embedding/req/EmbeddingRequest.java
================================================
package com.ai.baidu.endPoint.embedding.req;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * 嵌入请求体,官方文档链接:https://cloud.baidu.com/doc/WENXINWORKSHOP/s/alj562vvu
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class EmbeddingRequest {

    /**
     * 必传
     * 输入文本以获取embeddings。说明:
     * (1)不能为空List,List的每个成员不能为空字符串
     * (2)文本数量不超过16
     * (3)每个文本token数不超过384且长度不超过1000个字符
     */
    private List<String> input;

    /**
     * 表示最终用户的唯一标识符
     */
    @JsonProperty("user_id")
    private String userId;

    public static EmbeddingRequest baseBuild(List<String> input) {
        return EmbeddingRequest.builder().input(input).build();
    }

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/embedding/resp/EmbeddingResponse.java
================================================
package com.ai.baidu.endPoint.embedding.resp;

import com.ai.baidu.common.Usage;
import com.ai.baidu.endPoint.embedding.EmbeddingData;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * 嵌入返回体,官方文档链接:https://cloud.baidu.com/doc/WENXINWORKSHOP/s/alj562vvu
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class EmbeddingResponse {

    /**
     * 本轮对话的id
     */
    private String id;

    /**
     * 回包类型,固定值“embedding_list”
     */
    private String Object;

    /**
     * 时间戳
     */
    private Integer created;

    /**
     * embedding信息,data成员数和文本数量保持一致
     */
    private List<EmbeddingData> data;

    /**
     * token统计信息,token数 = 汉字数+单词数*1.3 (仅为估算逻辑)
     */
    private Usage usage;


}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/images/ImageData.java
================================================
package com.ai.baidu.endPoint.images;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ImageData {

    /**
     * 固定值"image"
     */
    private String object;

    /**
     * 图片base64编码内容
     */
    @JsonProperty("b64_image")
    private String b64Image;

    /**
     * 序号
     */
    private Integer index;

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/images/req/ImageRequest.java
================================================
package com.ai.baidu.endPoint.images.req;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import java.io.Serializable;

/**
 * 文生图,官方文档路径:https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Klkqubb9w#header%E5%8F%82%E6%95%B0
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ImageRequest implements Serializable {

    /**
     * 必传
     * 提示词,即用户希望图片包含的元素。长度限制为1024字符,建议中文或者英文单词总数量不超过150个
     */
    private String prompt;

    /**
     * 反向提示词,即用户希望图片不包含的元素。长度限制为1024字符,建议中文或者英文单词总数量不超过150个
     */
    @JsonProperty("negative_prompt")
    private String negativePrompt;

    /**
     * 生成图片长宽,默认值 1024x1024,取值范围如下:
     * ["768x768", "768x1024", "1024x768", "576x1024", "1024x576", "1024x1024"]
     */
    private String size;

    /**
     * 生成图片数量,说明:
     * · 默认值为1
     * · 取值范围为1-4
     * · 单次生成的图片较多及请求较频繁可能导致请求超时
     */
    private Integer n;

    /**
     * 迭代轮次,说明:
     * · 默认值为20
     * · 取值范围为10-50
     */
    private Integer steps;

    /**
     * 采样方式,默认值:Euler a,可选值如下(释义参考):
     * · Euler
     * · Euler a
     * · DPM++ 2M
     * · DPM++ 2M Karras
     * · LMS Karras
     * · DPM++ SDE
     * · DPM++ SDE Karras
     * · DPM2 a Karras
     * · Heun
     * · DPM++ 2M SDE
     * · DPM++ 2M SDE Karras
     * · DPM2
     * · DPM2 Karras
     * · DPM2 a
     * · LMS
     */
    @JsonProperty("sampler_index")
    private String samplerIndex;

    /**
     * 随机种子,说明:
     * · 不设置时,自动生成随机数
     * · 取值范围 [0, 4294967295]
     */
    private Integer seed;

    /**
     * 提示词相关性,说明:默认值为5,取值范围0-30
     */
    @JsonProperty("cfg_scale")
    private Double cfgScale;

    /**
     * 生成风格。说明:
     * (1)可选值:
     * · Base:基础风格
     * · 3D Model:3D模型
     * · Analog Film:模拟胶片
     * · Anime:动漫
     * · Cinematic:电影
     * · Comic Book:漫画
     * · Craft Clay:工艺黏土
     * · Digital Art:数字艺术
     * · Enhance:增强
     * · Fantasy Art:幻想艺术
     * · lsometric:等距风格
     * · Line Art:线条艺术
     * · Lowpoly:低多边形
     * · Neonpunk:霓虹朋克
     * · Origami:折纸
     * · Photographic:摄影
     * · Pixel Art:像素艺术
     * · Texture:纹理
     * (2)默认值为Base
     */
    private String style;

    /**
     * 表示最终用户的唯一标识符
     */
    @JsonProperty("user_id")
    private String userId;

    public static ImageRequest baseBuild(String prompt) {
        return ImageRequest.builder().prompt(prompt).build();
    }

    @Getter
    @AllArgsConstructor
    public enum ImgSize {
        SIZE_768_768("768x768"),
        SIZE_768_1024("768x1024"),
        SIZE_576_1024("576x1024"),
        SIZE_1024_768("1024x768"),
        SIZE_1024_576("1024x576"),
        SIZE_1024_1024("1024x1024"),
        ;
        private String size;
    }

    @Getter
    @AllArgsConstructor
    public enum ImgStyle {
        Base("Base"),
        model3D("3D Model"),
        AnalogFilm("Analog Film"),
        Anime("Anime"),
        Cinematic("Cinematic"),
        ComicBook("Comic Book"),
        CraftClay("Craft Clay"),
        DigitalArt("Digital Art"),
        Enhance("Enhance"),
        FantasyArt("Fantasy Art"),
        lsometric("lsometric"),
        LineArt("Line Art"),
        Lowpoly("Lowpoly"),
        Neonpunk("Neonpunk"),
        Origami("Origami"),
        Photographic("Photographic"),
        PixelArt("Pixel Art"),
        Texture("Texture"),
        ;
        private String style;
    }

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/images/resp/ImageResponse.java
================================================
package com.ai.baidu.endPoint.images.resp;

import com.ai.baidu.common.Usage;
import com.ai.baidu.endPoint.images.ImageData;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ImageResponse implements Serializable {

    /**
     * 请求的id
     */
    private String id;

    /**
     * 回包类型。image:图像生成返回
     */
    private String object;

    /**
     * 时间戳
     */
    private Integer created;

    /**
     * 生成图片结果
     */
    private List<ImageData> data;

    /**
     * token统计信息,token数 = 汉字数+单词数*1.3 (仅为估算逻辑)
     */
    private Usage usage;

}


================================================
FILE: ai-baidu/src/main/java/com/ai/baidu/interceptor/ResponseInterceptor.java
================================================
package com.ai.baidu.interceptor;

import lombok.extern.slf4j.Slf4j;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

/**
 * 返回信息拦截器
 */
@Slf4j
public class ResponseInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        // 1. 获取 req 和 resp
        Request original = chain.request();
        Response response = chain.proceed(original);
        if (!response.isSuccessful() && response.body() != null) {
            log.error("--------> 请求异常:{}", response.body().string());
        }
        return response;
    }
}


================================================
FILE: ai-baidu/src/test/java/com/ai/baidu/ChatApiTest.java
================================================
package com.ai.baidu;

import com.ai.baidu.achieve.ApiData;
import com.ai.baidu.achieve.Configuration;
import com.ai.baidu.achieve.defaults.DefaultBaiduSessionFactory;
import com.ai.baidu.achieve.standard.session.AggregationSession;
import com.ai.baidu.endPoint.chat.Message;
import com.ai.baidu.endPoint.chat.req.ChatRequest;
import com.ai.baidu.endPoint.chat.resp.ChatResponse;
import com.ai.core.strategy.impl.FirstKeyStrategy;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;

/**
 * @Description: 测试聊天接口相关接口功能
 */
@Slf4j
public class ChatApiTest {

    private AggregationSession aggregationSession;

    private Configuration configuration;

    @Before
    public void test_BaiduSessionFactory() {
        // 1. 创建配置类
        this.configuration = new Configuration();
        // 2. 设置请求地址,若有代理商或者代理服务器,可填写为代理服务器的请求路径
        configuration.setApiHost("https://aip.baidubce.com");
        // 3. 设置鉴权所需的API Key,可设置多个。
        ApiData apiData = ApiData.builder()
                .apiKey("**************************")
                .secretKey("**************************")
                .appId("**************************")
                .build();
        configuration.setKeyList(Arrays.asList(apiData));
        // 4. 设置请求时 key 的使用策略,默认实现了:随机获取 和 固定第一个Key 两种方式。
        configuration.setKeyStrategy(new FirstKeyStrategy<ApiData>());
//        configuration.setKeyStrategy(new RandomKeyStrategy<ApiData>());
        // 5. 设置代理,若不需要可不设置
//        configuration.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890)));
        // 6. 创建 session 工厂,制造不同场景的 session
        DefaultBaiduSessionFactory factory = new DefaultBaiduSessionFactory(configuration);
        this.aggregationSession = factory.openAggregationSession();
    }

    /**
     * 测试鉴权接口
     */
    @Test
    public void test_auth() {
        // 获取用户配置的ApiData
        ApiData systemApiData = configuration.getSystemApiData();
        // 鉴权
        String accessToken = configuration.getBaiduApiServer().getAccessToken(systemApiData.getApiKey(), systemApiData.getSecretKey());
        System.out.println(accessToken);
    }

    /**
     * 测试聊天功能
     */
    @Test
    public void test_chat() {
        // 发起聊天,chat接口如果传入的 accessToken 为空,会自动根据用户设置的信息进行鉴权
        ChatResponse response = aggregationSession
                .getChatSession()// 获取 chatSession
                .chat(null, ChatRequest.baseBuild(Message.Role.USER, "Introduce the city Beijing"));// 构造一个基础的聊天请求体
        System.out.println(response.getResult());
        System.out.println(response.getUsage());
    }

    @Test
    public void test_chat_multiple() {
        // 构造对话
        Message msg1 = Message.baseBuild(Message.Role.USER, "请记住我的名字叫小明");
        Message msg2 = Message.baseBuild(Message.Role.ASSISTANT, "好的");
        Message msg3 = Message.baseBuild(Message.Role.USER, "我的名字叫什么?");
        ArrayList<Message> messages = new ArrayList<>();
        messages.add(msg1);
        messages.add(msg2);
        messages.add(msg3);
        // 构造参数
        ChatRequest request = ChatRequest.builder().messages(messages).build();
        // 发起请求
        ChatResponse response = aggregationSession.getChatSession().chat(null, request);
        System.out.println(response.getResult());
        System.out.println(response.getUsage());
    }

    @Test
    public void test_chat_stream() throws InterruptedException {
        ChatRequest request = ChatRequest.baseBuild(Message.Role.USER, "你能讲一个笑话吗?");
        request.setStream(true);// 设置流式返回
        // 发起聊天,chat接口如果传入的 accessToken 为空,会自动根据用户设置的信息进行鉴权
        aggregationSession.getChatSession()// 获取 chatSession
                .chat(null, request, new EventSourceListener() {
                    @Override
                    public void onEvent(@NotNull EventSource eventSource, @Nullable String id, @Nullable String type, @NotNull String data) {
                        log.info("测试结果 id:{} type:{} data:{}", id, type, data);
                    }

                    @Override
                    public void onFailure(@NotNull EventSource eventSource, @Nullable Throwable t, @Nullable Response response) {
                        log.error("失败 code:{} message:{}", response.code(), response.message());
                    }
                });
        new CountDownLatch(1).await();
    }

}


================================================
FILE: ai-baidu/src/test/java/com/ai/baidu/EmbeddingApiTest.java
================================================
package com.ai.baidu;

import com.ai.baidu.achieve.ApiData;
import com.ai.baidu.achieve.Configuration;
import com.ai.baidu.achieve.defaults.DefaultBaiduSessionFactory;
import com.ai.baidu.achieve.standard.session.AggregationSession;
import com.ai.baidu.endPoint.embedding.EmbeddingData;
import com.ai.baidu.endPoint.embedding.req.EmbeddingRequest;
import com.ai.baidu.endPoint.embedding.resp.EmbeddingResponse;
import com.ai.core.strategy.impl.FirstKeyStrategy;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Description: 嵌入相关功能点测试
 **/
public class EmbeddingApiTest {

    private AggregationSession aggregationSession;

    private Configuration configuration;

    @Before
    public void test_BaiduSessionFactory() {
        // 1. 创建配置类
        this.configuration = new Configuration();
        // 2. 设置请求地址,若有代理商或者代理服务器,可填写为代理服务器的请求路径
        configuration.setApiHost("https://aip.baidubce.com");
        // 3. 设置鉴权所需的API Key,可设置多个。
        ApiData apiData = ApiData.builder()
                .apiKey("**************************")
                .secretKey("**************************")
                .appId("**************************")
                .build();
        configuration.setKeyList(Arrays.asList(apiData));
        // 4. 设置请求时 key 的使用策略,默认实现了:随机获取 和 固定第一个Key 两种方式。
        configuration.setKeyStrategy(new FirstKeyStrategy<ApiData>());
//        configuration.setKeyStrategy(new RandomKeyStrategy<ApiData>());
        // 5. 设置代理,若不需要可不设置
//        configuration.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890)));
        // 6. 创建 session 工厂,制造不同场景的 session
        DefaultBaiduSessionFactory factory = new DefaultBaiduSessionFactory(configuration);
        this.aggregationSession = factory.openAggregationSession();
    }

    /**
     * 测试嵌入接口
     */
    @Test
    public void test_embedding() {
        List<String> input = new ArrayList<>();
        input.add("你好");
        input.add("世界");
        EmbeddingRequest embeddingRequest = EmbeddingRequest.baseBuild(input);
        EmbeddingResponse embeddingResponse = aggregationSession.getEmbeddingSession().embedding(null, embeddingRequest);
        for (EmbeddingData e : embeddingResponse.getData()) {
            System.out.println(e);
        }
    }

}


================================================
FILE: ai-baidu/src/test/java/com/ai/baidu/ImageApiTest.java
================================================
package com.ai.baidu;


import com.ai.baidu.achieve.ApiData;
import com.ai.baidu.achieve.Configuration;
import com.ai.baidu.achieve.defaults.DefaultBaiduSessionFactory;
import com.ai.baidu.achieve.standard.session.AggregationSession;
import com.ai.baidu.endPoint.images.ImageData;
import com.ai.baidu.endPoint.images.req.ImageRequest;
import com.ai.baidu.endPoint.images.resp.ImageResponse;
import com.ai.common.utils.ImageUtils;
import com.ai.core.strategy.impl.FirstKeyStrategy;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

/**
 * @Description: 图片相关功能点测试
 **/
public class ImageApiTest {

    private AggregationSession aggregationSession;

    private Configuration configuration;

    @Before
    public void test_BaiduSessionFactory() {
        // 1. 创建配置类
        this.configuration = new Configuration();
        // 2. 设置请求地址,若有代理商或者代理服务器,可填写为代理服务器的请求路径
        configuration.setApiHost("https://aip.baidubce.com");
        // 3. 设置鉴权所需的API Key,可设置多个。
        ApiData apiData = ApiData.builder()
                .apiKey("**************************")
                .secretKey("**************************")
                .appId("**************************")
                .build();
        configuration.setKeyList(Arrays.asList(apiData));
        // 4. 设置请求时 key 的使用策略,默认实现了:随机获取 和 固定第一个Key 两种方式。
        configuration.setKeyStrategy(new FirstKeyStrategy<ApiData>());
//        configuration.setKeyStrategy(new RandomKeyStrategy<ApiData>());
        // 5. 设置代理,若不需要可不设置
//        configuration.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890)));
        // 6. 创建 session 工厂,制造不同场景的 session
        DefaultBaiduSessionFactory factory = new DefaultBaiduSessionFactory(configuration);
        this.aggregationSession = factory.openAggregationSession();
    }

    @Test
    public void test_text2image() {
        ImageRequest imageRequest = ImageRequest.baseBuild("画一个哆啦A梦");
        ImageResponse imageResponse = aggregationSession.getImageSession().text2image(imageRequest);
        // 得到结果当中的base64 图片字符串
        List<ImageData> data = imageResponse.getData();
        for (int i = 0; i < data.size(); i++) {
            ImageUtils.convertBase64StrToImage(data.get(i).getB64Image(), "D:\\chatGPT-api\\AI-java\\doc\\test\\test_baidu_create_image_" + i + ".png");
        }
    }

}


================================================
FILE: ai-common/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>AI-java</artifactId>
        <groupId>com.ai</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ai-common</artifactId>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <retrofit2.version>2.9.0</retrofit2.version>
        <slf4j.version>2.0.6</slf4j.version>
        <gson.version>2.8.5</gson.version>
        <jackson.version>2.13.3</jackson.version>
        <hutool.version>5.8.18</hutool.version>
        <okhttp.version>4.9.3</okhttp.version>
        <logging-interceptor.version>4.10.0</logging-interceptor.version>
        <lombok.version>1.18.26</lombok.version>
        <jtokkit.version>0.2.0</jtokkit.version>
        <fastjson.version>2.0.32</fastjson.version>
        <junit.version>4.13.2</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>${gson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp-sse</artifactId>
            <version>${okhttp.version}</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>logging-interceptor</artifactId>
            <version>${logging-interceptor.version}</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.retrofit2</groupId>
            <artifactId>retrofit</artifactId>
            <version>${retrofit2.version}</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.retrofit2</groupId>
            <artifactId>converter-jackson</artifactId>
            <version>${retrofit2.version}</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.retrofit2</groupId>
            <artifactId>adapter-rxjava2</artifactId>
            <version>${retrofit2.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jetbrains</groupId>
            <artifactId>annotations</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.knuddels</groupId>
            <artifactId>jtokkit</artifactId>
            <version>${jtokkit.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>
    </dependencies>

</project>


================================================
FILE: ai-common/src/main/java/com/ai/common/utils/Exceptions.java
================================================
package com.ai.common.utils;

/**
 * 异常工具类
 */
public class Exceptions {

    public static IllegalArgumentException illegalArgument(String format, Object... args) {
        return new IllegalArgumentException(String.format(format, args));
    }

    public static RuntimeException runtime(String format, Object... args) {
        return new RuntimeException(String.format(format, args));
    }
}


================================================
FILE: ai-common/src/main/java/com/ai/common/utils/ImageUtils.java
================================================
package com.ai.common.utils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Base64;

public class ImageUtils {

    /**
     * 图片转Base64字符串
     *
     * @param imageFileName
     * @return
     */
    public static String convertImageToBase64Str(String imageFileName) {
        ByteArrayOutputStream baos = null;
        try {
            //获取图片类型
            String suffix = imageFileName.substring(imageFileName.lastIndexOf(".") + 1);
            //构建文件
            File imageFile = new File(imageFileName);
            //通过ImageIO把文件读取成BufferedImage对象
            BufferedImage bufferedImage = ImageIO.read(imageFile);
            //构建字节数组输出流
            baos = new ByteArrayOutputStream();
            //写入流
            ImageIO.write(bufferedImage, suffix, baos);
            //通过字节数组流获取字节数组
            byte[] bytes = baos.toByteArray();
            //获取JDK8里的编码器Base64.Encoder转为base64字符
            return Base64.getEncoder().encodeToString(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Base64字符串转图片
     *
     * @param base64String
     * @param imageFileName
     */
    public static void convertBase64StrToImage(String base64String, String imageFileName) {
        ByteArrayInputStream bais = null;
        try {
            //获取图片类型
            String suffix = imageFileName.substring(imageFileName.lastIndexOf(".") + 1);
            //获取JDK8里的解码器Base64.Decoder,将base64字符串转为字节数组
            byte[] bytes = Base64.getDecoder().decode(base64String);
            //构建字节数组输入流
            bais = new ByteArrayInputStream(bytes);
            //通过ImageIO把字节数组输入流转为BufferedImage
            BufferedImage bufferedImage = ImageIO.read(bais);
            //构建文件
            File imageFile = new File(imageFileName);
            //写入生成文件
            ImageIO.write(bufferedImage, suffix, imageFile);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bais != null) {
                    bais.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}


================================================
FILE: ai-common/src/main/java/com/ai/common/utils/JsonUtils.java
================================================
package com.ai.common.utils;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonUtils {

    public static final ObjectMapper objectMapper = new ObjectMapper();

    public static <T> T fromJson(String json, Class<T> valueType) {
        try {
            return objectMapper.readValue(json, valueType);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String toJson(Object object) {
        try {
            return objectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}



================================================
FILE: ai-common/src/main/java/com/ai/common/utils/ValidationUtils.java
================================================
package com.ai.common.utils;

import java.util.Collection;

import static com.ai.common.utils.Exceptions.illegalArgument;


public class ValidationUtils {

    public static <T> T ensureNotNull(T object, String name) {
        if (object == null) {
            throw illegalArgument("%s cannot be null", name);
        }

        return object;
    }

    public static <T extends Collection<?>> T ensureNotEmpty(T collection, String name) {
        if (collection == null || collection.isEmpty()) {
            throw illegalArgument("%s cannot be null or empty", name);
        }

        return collection;
    }

    public static String ensureNotBlank(String string, String name) {
        if (string == null || string.trim().isEmpty()) {
            throw illegalArgument("%s cannot be null or blank", name);
        }

        return string;
    }

    public static void ensureTrue(boolean expression, String msg) {
        if (!expression) {
            throw illegalArgument(msg);
        }
    }

    public static int ensureGreaterThanZero(Integer i, String name) {
        if (i == null || i <= 0) {
            throw illegalArgument("%s must be greater than zero, but is: %s", name, i);
        }

        return i;
    }

    public static double ensureBetween(Double d, double min, double max, String name) {
        if (d == null || d < min || d > max) {
            throw illegalArgument("%s must be between %s and %s, but is: %s", name, min, max, d);
        }

        return d;
    }

    public static int ensureBetween(Integer i, int min, int max, String name) {
        if (i == null || i < min || i > max) {
            throw illegalArgument("%s must be between %s and %s, but is: %s", name, min, max, i);
        }

        return i;
    }
}



================================================
FILE: ai-core/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>AI-java</artifactId>
        <groupId>com.ai</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>ai-core</artifactId>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.ai</groupId>
            <artifactId>ai-common</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>

</project>


================================================
FILE: ai-core/src/main/java/com/ai/core/config/BaseConfiguration.java
================================================
package com.ai.core.config;

import com.ai.core.strategy.KeyStrategy;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import okhttp3.OkHttpClient;
import org.jetbrains.annotations.NotNull;

import java.net.Proxy;

/**
 * 各个模型配置基础类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BaseConfiguration {

    /**
     * api 请求客户端
     */
    private OkHttpClient okHttpClient;

    /**
     * 请求地址(很多情况下,这个apiHost都是一个摆设)
     */
    @NotNull
    private String apiHost;

    /**
     * 代理信息
     */
    private Proxy proxy;

    /**
     * 获取key的策略
     */
    private KeyStrategy keyStrategy;

}


================================================
FILE: ai-core/src/main/java/com/ai/core/exception/BaseException.java
================================================
package com.ai.core.exception;

import lombok.Getter;

@Getter
public class BaseException extends RuntimeException {

    private final String msg;
    private final int code;

    public BaseException(IError error) {
        super(error.msg());
        this.code = error.code();
        this.msg = error.msg();
    }

    public BaseException(String msg) {
        super(msg);
        this.code = Constants.ErrorMsg.SYS_ERROR.code();
        this.msg = msg;
    }

    public BaseException() {
        super(Constants.ErrorMsg.SYS_ERROR.msg());
        this.code = Constants.ErrorMsg.SYS_ERROR.code();
        this.msg = Constants.ErrorMsg.SYS_ERROR.msg();
    }
}


================================================
FILE: ai-core/src/main/java/com/ai/core/exception/Constants.java
================================================
package com.ai.core.exception;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.HashMap;
import java.util.Map;

/**
 * @description 通用类
 */
public class Constants {

    public static final String NULL = "NULL";
    public static final String API_KEY = "apiKey";
    public static final String API_HOST = "apiHost";
    public static final String URL = "url";
    public static final Map<Integer, String> ERROR_MSG_MAP = new HashMap<>();

    static {
        ERROR_MSG_MAP.put(ErrorMsg.OPENAI_AUTHENTICATION_ERROR.code(), ErrorMsg.OPENAI_AUTHENTICATION_ERROR.msg());
        ERROR_MSG_MAP.put(ErrorMsg.OPENAI_LIMIT_ERROR.code(), ErrorMsg.OPENAI_LIMIT_ERROR.msg());
        ERROR_MSG_MAP.put(ErrorMsg.OPENAI_SERVER_ERROR.code(), ErrorMsg.OPENAI_SERVER_ERROR.msg());
    }

    public enum ErrorMsg implements IError {
        MESSAGE_NOT_NUL(500, "Message 不能为空"),
        API_KEYS_NOT_NUL(500, "API KEYS 不能为空"),
        NO_ACTIVE_API_KEYS(500, "没有可用的API KEYS"),
        SYS_ERROR(500, "系统繁忙"),
        PARAM_ERROR(501, "参数异常"),
        RETRY_ERROR(502, "请求异常,请重试~"),
        OPENAI_AUTHENTICATION_ERROR(401, "身份验证无效/提供的 API 密钥不正确/您必须是组织的成员才能使用 API"),
        OPENAI_LIMIT_ERROR(429, "达到请求的速率限制/您超出了当前配额,请检查您的计划和帐单详细信息/发动机当前过载,请稍后重试"),
        OPENAI_SERVER_ERROR(500, "服务器在处理您的请求时出错"),
        ;
        private int code;
        private String msg;

        ErrorMsg(int code, String msg) {
            this.code = code;
            this.msg = msg;
        }

        public String msg() {
            return this.msg;
        }

        public int code() {
            return this.code;
        }
    }


    /**
     * 官网支持的请求角色类型为:system、user、assistant
     * system:用来设置 assistant 的行为
     * user:用于指导 assistant
     * assistant:消息帮助存储更早的响应
     */
    @Getter
    @AllArgsConstructor
    public enum Role {

        SYSTEM("system"),
        USER("user"),
        ASSISTANT("assistant"),
        ;

        private String RoleName;
    }

}


================================================
FILE: ai-core/src/main/java/com/ai/core/exception/IError.java
================================================
package com.ai.core.exception;

public interface IError {

    String msg();

    int code();

}


================================================
FILE: ai-core/src/main/java/com/ai/core/factory/SessionFactory.java
================================================
package com.ai.core.factory;


import okhttp3.OkHttpClient;

public interface SessionFactory<Session, ApiServer> {

    /**
     * 创建聚合过后的session
     *
     * @return 默认的聚合session
     */
    Session openAggregationSession();

    /**
     * 获取 Api 信息
     *
     * @param okHttpClient 客户端
     * @return api信息
     */
    ApiServer createApiServer(OkHttpClient okHttpClient);

    /**
     * 获取 httpClient
     *
     * @return 客户端
     */
    OkHttpClient createHttpClient();

}


================================================
FILE: ai-core/src/main/java/com/ai/core/strategy/KeyStrategy.java
================================================
package com.ai.core.strategy;


/**
 * @Description: API Key 获取策略
 */
public interface KeyStrategy<T, R> {
    R apply(T t);
}


================================================
FILE: ai-core/src/main/java/com/ai/core/strategy/impl/FirstKeyStrategy.java
================================================
package com.ai.core.strategy.impl;

import com.ai.core.strategy.KeyStrategy;

import java.util.List;


public class FirstKeyStrategy<T> implements KeyStrategy<List<T>, T> {

    @Override
    public T apply(List<T> keyList) {
        return keyList.get(0);
    }
}


================================================
FILE: ai-core/src/main/java/com/ai/core/strategy/impl/RandomKeyStrategy.java
================================================
package com.ai.core.strategy.impl;

import cn.hutool.core.util.RandomUtil;
import com.ai.core.strategy.KeyStrategy;

import java.util.List;


public class RandomKeyStrategy<T> implements KeyStrategy<List<T>, T> {

    @Override
    public T apply(List<T> keyList) {
        return RandomUtil.randomEle(keyList);
    }

}


================================================
FILE: ai-openai/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>AI-java</artifactId>
        <groupId>com.ai</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>ai-openai</artifactId>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>4.13.2</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.ai</groupId>
            <artifactId>ai-common</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>com.ai</groupId>
            <artifactId>ai-core</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>



================================================
FILE: ai-openai/src/main/java/com/ai/openai/Product.java
================================================
package com.ai.openai;

public class Product {

    private String str1;
    private String str2;

    public Product(Builder builder) {
        this.str1 = builder.str1;
        this.str2 = builder.str2;
    }

    public static void main(String[] args) {
        Product build = new Builder().setStr1("str1").setStr2("str2").build();
    }

    public static class Builder {
        private static String str1;
        private static String str2;

        public Builder() {
        }

        public Builder setStr1(String str1) {
            this.str1 = str1;
            return this;
        }

        public Builder setStr2(String str2) {
            this.str2 = str2;
            return this;
        }

        public Product build() {
            return new Product(this);
        }
    }

}






================================================
FILE: ai-openai/src/main/java/com/ai/openai/Singleton.java
================================================
package com.ai.openai;


public class Singleton {

    private static volatile Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/ThreadPrint.java
================================================
package com.ai.openai;


import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class LockPrinter {
    private static final Lock lock = new ReentrantLock();
    private static final Condition condition = lock.newCondition();
    private static int number = 0;

    public static void main(String[] args) {
        new Thread(() -> LockPrinter.printNumber(1), "A").start();
        new Thread(() -> LockPrinter.printNumber(2), "B").start();
        new Thread(() -> LockPrinter.printNumber(3), "C").start();
    }

    public static void printNumber(int target) {
        while (number <= 10) {
            try {
                lock.lock();
                if ((number % 3 + 1) != target) condition.await();
                else {
                    System.out.println(Thread.currentThread().getName() + " : " + target);
                    number++;
                    condition.signalAll();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
}

class SyncPrinter {

    private static int number = 0;

    public static void main(String[] args) {
        new Thread(() -> SyncPrinter.printNumber(1), "A").start();
        new Thread(() -> SyncPrinter.printNumber(2), "B").start();
        new Thread(() -> SyncPrinter.printNumber(3), "C").start();
    }

    public static void printNumber(int target) {
        while (number <= 10) {
            if (number % 3 + 1 == target)
                synchronized (SyncPrinter.class) {
                    if (number % 3 + 1 == target) {
                        System.out.println(Thread.currentThread().getName() + " : " + target);
                        number++;
                    }
                }
        }
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/Configuration.java
================================================
package com.ai.openai.achieve;

import com.ai.core.config.BaseConfiguration;
import com.ai.openai.achieve.standard.api.OpenaiApiServer;
import lombok.*;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSources;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
 * @Description: openai 相关配置信息
 **/
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class Configuration extends BaseConfiguration {

    /**
     * api 服务提供者
     */
    private OpenaiApiServer openaiApiServer;

    /**
     * api Key 集合
     */
    @NotNull
    private List<String> keyList;

    public EventSource.Factory createRequestFactory() {
        return EventSources.createFactory(this.getOkHttpClient());
    }


    public String getSystemApiData() {
        return (String) this.getKeyStrategy().apply(keyList);
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/DefaultOpenAiSessionFactory.java
================================================
package com.ai.openai.achieve.defaults;


import com.ai.core.factory.SessionFactory;
import com.ai.openai.achieve.Configuration;
import com.ai.openai.achieve.defaults.session.DefaultAggregationSession;
import com.ai.openai.achieve.standard.api.OpenaiApiServer;
import com.ai.openai.achieve.standard.session.AggregationSession;
import com.ai.openai.interceptor.HeaderInterceptor;
import com.ai.openai.interceptor.ResponseInterceptor;
import lombok.AllArgsConstructor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;

import java.util.concurrent.TimeUnit;

/**
 * @description OpenAi API Factory 会话工厂
 */
@AllArgsConstructor
public class DefaultOpenAiSessionFactory implements SessionFactory<AggregationSession, OpenaiApiServer> {

    private final Configuration configuration;

    @Override
    public OkHttpClient createHttpClient() {
        // 1. 日志配置
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.NONE);
        // 2. 开启 Http 客户端
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .addInterceptor(httpLoggingInterceptor)
                .addInterceptor(new HeaderInterceptor(configuration.getKeyList(), configuration.getApiHost(), configuration.getKeyStrategy()))
                .addInterceptor(new ResponseInterceptor())
                .connectTimeout(450, TimeUnit.SECONDS)
                .writeTimeout(450, TimeUnit.SECONDS)
                .readTimeout(450, TimeUnit.SECONDS);
        // 3. 检查是否需要代理
        if (configuration.getProxy() != null) {
            builder.proxy(configuration.getProxy());
        }
        return builder.build();
    }

    @Override
    public OpenaiApiServer createApiServer(OkHttpClient okHttpClient) {
        return new Retrofit.Builder()
                .baseUrl(configuration.getApiHost())
                .client(okHttpClient)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(JacksonConverterFactory.create())
                .build().create(OpenaiApiServer.class);
    }

    @Override
    public AggregationSession openAggregationSession() {
        OkHttpClient okHttpClient = createHttpClient();
        configuration.setOkHttpClient(okHttpClient);
        configuration.setOpenaiApiServer(createApiServer(okHttpClient));
        return new DefaultAggregationSession(configuration);
    }
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultAggregationSession.java
================================================
package com.ai.openai.achieve.defaults.session;

import com.ai.openai.achieve.Configuration;
import com.ai.openai.achieve.standard.session.*;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;

/**
 * @Description: 聚合各个类型的session
 **/
public class DefaultAggregationSession implements AggregationSession {

    private Configuration configuration;

    private volatile AudioSession audioSession;

    private volatile ChatSession chatSession;

    private volatile EmbeddingSession embeddingSession;

    private volatile FineTuningSession fineTuningSession;

    private volatile FilesSession filesSession;

    private volatile ImageSession imageSession;

    private volatile ModelSession modelSession;

    private volatile ModerationSession moderationSession;

    public DefaultAggregationSession(Configuration configuration) {
        this.configuration = ensureNotNull(configuration, "configuration");
    }

    public Configuration getConfiguration() {
        return configuration;
    }

    @Override
    public AudioSession getAudioSession() {
        if (audioSession == null) {
            synchronized (this) {
                if (audioSession == null) {
                    audioSession = new DefaultAudioSession(configuration);
                }
            }
        }
        return audioSession;
    }

    @Override
    public ChatSession getChatSession() {
        if (chatSession == null) {
            synchronized (this) {
                if (chatSession == null) {
                    chatSession = new DefaultChatSession(configuration);
                }
            }
        }
        return chatSession;
    }

    @Override
    public FineTuningSession getFineTuningSession() {
        if (fineTuningSession == null) {
            synchronized (this) {
                if (fineTuningSession == null) {
                    fineTuningSession = new DefaultFineTuningSession(configuration);
                }
            }
        }
        return fineTuningSession;
    }

    @Override
    public EmbeddingSession getEmbeddingSession() {
        if (embeddingSession == null) {
            synchronized (this) {
                if (embeddingSession == null) {
                    embeddingSession = new DefaultEmbeddingSession(configuration);
                }
            }
        }
        return embeddingSession;
    }

    @Override
    public FilesSession getFilesSession() {
        if (filesSession == null) {
            synchronized (this) {
                if (filesSession == null) {
                    filesSession = new DefaultFilesSession(configuration);
                }
            }
        }
        return filesSession;
    }

    @Override
    public ImageSession getImageSession() {
        if (imageSession == null) {
            synchronized (this) {
                if (imageSession == null) {
                    imageSession = new DefaultImageSession(configuration);
                }
            }
        }
        return imageSession;
    }

    @Override
    public ModelSession getModelSession() {
        if (modelSession == null) {
            synchronized (this) {
                if (modelSession == null) {
                    modelSession = new DefaultModelSession(configuration);
                }
            }
        }
        return modelSession;
    }

    @Override
    public ModerationSession getModerationSession() {
        if (moderationSession == null) {
            synchronized (this) {
                if (moderationSession == null) {
                    moderationSession = new DefaultModerationSession(configuration);
                }
            }
        }
        return moderationSession;
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultAudioSession.java
================================================
package com.ai.openai.achieve.defaults.session;

import cn.hutool.core.util.StrUtil;
import com.ai.openai.achieve.Configuration;
import com.ai.openai.achieve.standard.session.AudioSession;
import com.ai.openai.endPoint.audio.req.SttCompletionRequest;
import com.ai.openai.endPoint.audio.req.TtsCompletionRequest;
import com.ai.openai.endPoint.audio.resp.SttCompletionResponse;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Callback;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;

/**
 * @Description: OpenAI 语音类会话
 **/
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class DefaultAudioSession extends Session implements AudioSession {

    public DefaultAudioSession(Configuration configuration) {
        this.setConfiguration(ensureNotNull(configuration, "configuration"));
        this.setOpenaiApiServer(ensureNotNull(configuration.getOpenaiApiServer(), "openaiApiServer"));
    }

    @Override
    public void ttsCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, TtsCompletionRequest ttsCompletionRequest, Callback callback) {
        this.getOpenaiApiServer().createSpeechCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, ttsCompletionRequest).enqueue(callback);
    }

    private SttCompletionResponse sttBaseCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, SttCompletionRequest sttCompletionRequest, String type) {
        RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), sttCompletionRequest.getFile());
        MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", sttCompletionRequest.getFile().getName(), fileBody);
        Map<String, RequestBody> requestBodyMap = new HashMap<>();
        if (StrUtil.isNotBlank(sttCompletionRequest.getLanguage())) {
            requestBodyMap.put(SttCompletionRequest.Fields.language, RequestBody.create(MediaType.parse("multipart/form-data"), sttCompletionRequest.getLanguage()));
        }
        if (StrUtil.isNotBlank(sttCompletionRequest.getModel())) {
            requestBodyMap.put(SttCompletionRequest.Fields.model, RequestBody.create(MediaType.parse("multipart/form-data"), sttCompletionRequest.getModel()));
        }
        if (StrUtil.isNotBlank(sttCompletionRequest.getPrompt())) {
            requestBodyMap.put(SttCompletionRequest.Fields.prompt, RequestBody.create(MediaType.parse("multipart/form-data"), sttCompletionRequest.getPrompt()));
        }
        if (StrUtil.isNotBlank(sttCompletionRequest.getResponseFormat())) {
            requestBodyMap.put(SttCompletionRequest.Fields.responseFormat, RequestBody.create(MediaType.parse("multipart/form-data"), sttCompletionRequest.getResponseFormat()));
        }
        if (Objects.nonNull(sttCompletionRequest.getTemperature())) {
            requestBodyMap.put(SttCompletionRequest.Fields.temperature, RequestBody.create(MediaType.parse("multipart/form-data"), String.valueOf(sttCompletionRequest.getTemperature())));
        }
        if ("translation".equals(type)) {
            return this.getOpenaiApiServer().createTranslationCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, multipartBody, requestBodyMap).blockingGet();
        }
        return this.getOpenaiApiServer().createTranscriptionCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, multipartBody, requestBodyMap).blockingGet();
    }

    @Override
    public SttCompletionResponse sttCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, SttCompletionRequest sttCompletionRequest) {
        return sttBaseCompletions(apiHostByUser, apiKeyByUser, apiUrlByUser, sttCompletionRequest, "stt");
    }

    @Override
    public SttCompletionResponse translationCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, SttCompletionRequest sttCompletionRequest) {
        return sttBaseCompletions(apiHostByUser, apiKeyByUser, apiUrlByUser, sttCompletionRequest, "translation");
    }


}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultChatSession.java
================================================
package com.ai.openai.achieve.defaults.session;


import cn.hutool.http.ContentType;
import com.ai.common.utils.JsonUtils;
import com.ai.core.exception.Constants;
import com.ai.openai.achieve.Configuration;
import com.ai.openai.achieve.standard.session.ChatSession;
import com.ai.openai.common.ApiUrl;
import com.ai.openai.endPoint.chat.ChatChoice;
import com.ai.openai.endPoint.chat.msg.DefaultMessage;
import com.ai.openai.endPoint.chat.req.DefaultChatCompletionRequest;
import com.ai.openai.endPoint.chat.req.FuncChatCompletionRequest;
import com.ai.openai.endPoint.chat.req.ImgChatCompletionRequest;
import com.ai.openai.endPoint.chat.req.QaCompletionRequest;
import com.ai.openai.endPoint.chat.resp.ChatCompletionResponse;
import com.ai.openai.endPoint.chat.resp.QaCompletionResponse;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;

import java.util.List;
import java.util.concurrent.CompletableFuture;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;
import static com.ai.core.exception.Constants.*;

/**
 * @description OpenAI 对话类会话
 */
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class DefaultChatSession extends Session implements ChatSession {

    /**
     * 工厂事件
     */
    private EventSource.Factory factory;

    public DefaultChatSession(Configuration configuration) {
        this.setConfiguration(ensureNotNull(configuration, "configuration"));
        this.setOpenaiApiServer(ensureNotNull(configuration.getOpenaiApiServer(), "openaiApiServer"));
        this.setFactory(ensureNotNull(configuration.createRequestFactory(), "requestFactory"));
    }

    @Override
    public QaCompletionResponse qaCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, QaCompletionRequest qaCompletionRequest) {
        return this.getOpenaiApiServer().createQaCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, qaCompletionRequest).blockingGet();
    }

    @Override
    public EventSource qaCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, QaCompletionRequest qaCompletionRequest, EventSourceListener eventSourceListener) {
        Request request = new Request.Builder()
                .addHeader(API_HOST, apiHostByUser)
                .addHeader(API_KEY, apiKeyByUser)
                .addHeader(URL, apiUrlByUser)
                .url(this.getConfiguration().getApiHost().concat(ApiUrl.v1_completions.getUrl()))
                .post(RequestBody.create(MediaType.parse(ContentType.JSON.getValue()), JsonUtils.toJson(qaCompletionRequest)))
                .build();
        return factory.newEventSource(request, eventSourceListener);
    }

    @Override
    public ChatCompletionResponse chatCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, DefaultChatCompletionRequest defaultChatCompletionRequest) {
        return this.getOpenaiApiServer().createChatCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, defaultChatCompletionRequest).blockingGet();
    }

    @Override
    public ChatCompletionResponse chatCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, ImgChatCompletionRequest imgChatCompletionRequest) {
        return this.getOpenaiApiServer().createChatCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, imgChatCompletionRequest).blockingGet();
    }

    @Override
    public ChatCompletionResponse chatCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, FuncChatCompletionRequest funcChatCompletionRequest) {
        return this.getOpenaiApiServer().createChatCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, funcChatCompletionRequest).blockingGet();
    }

    @Override
    public EventSource chatCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, DefaultChatCompletionRequest defaultChatCompletionRequest, EventSourceListener eventSourceListener) throws JsonProcessingException {
        Request request = new Request.Builder()
                .addHeader(API_HOST, apiHostByUser)
                .addHeader(API_KEY, apiKeyByUser)
                .addHeader(URL, apiUrlByUser)
                .url(this.getConfiguration().getApiHost().concat(ApiUrl.v1_chat_completions.getUrl()))
                .post(RequestBody.create(MediaType.parse(ContentType.JSON.getValue()), new ObjectMapper().writeValueAsString(defaultChatCompletionRequest)))
                .build();
        return factory.newEventSource(request, eventSourceListener);
    }

    @Override
    public CompletableFuture<String> chatCompletionsFuture(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, DefaultChatCompletionRequest defaultChatCompletionRequest) throws JsonProcessingException {
        CompletableFuture<String> future = new CompletableFuture<>();
        StringBuffer dataBuffer = new StringBuffer();
        chatCompletions(apiHostByUser, apiKeyByUser, apiUrlByUser, defaultChatCompletionRequest, new EventSourceListener() {
            @Override
            public void onEvent(EventSource eventSource, String id, String type, String data) {
                if ("[DONE]".equalsIgnoreCase(data)) {
                    onClosed(eventSource);
                    future.complete(dataBuffer.toString());
                }
                ChatCompletionResponse chatCompletionResponse = JSON.parseObject(data, ChatCompletionResponse.class);
                List<ChatChoice> choices = chatCompletionResponse.getChoices();
                for (ChatChoice chatChoice : choices) {
                    DefaultMessage delta = chatChoice.getDelta();
                    if (Constants.Role.ASSISTANT.getRoleName().equals(delta.getRole())) continue;
                    // 应答完成
                    String finishReason = chatChoice.getFinishReason();
                    if ("stop".equalsIgnoreCase(finishReason)) {
                        onClosed(eventSource);
                        return;
                    }
                    // 发送信息
                    try {
                        dataBuffer.append(delta.getContent());
                    } catch (Exception e) {
                        future.completeExceptionally(new RuntimeException("Request closed before completion"));
                    }
                }
            }

            @Override
            public void onClosed(EventSource eventSource) {
                future.complete(dataBuffer.toString());
            }

            @Override
            public void onFailure(EventSource eventSource, Throwable t, Response response) {
                future.completeExceptionally(new RuntimeException("Request closed before completion"));
            }
        });
        return future;
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultEmbeddingSession.java
================================================
package com.ai.openai.achieve.defaults.session;

import com.ai.openai.achieve.Configuration;
import com.ai.openai.achieve.standard.session.EmbeddingSession;
import com.ai.openai.endPoint.embeddings.EmbeddingObject;
import com.ai.openai.endPoint.embeddings.req.EmbeddingCompletionRequest;
import com.ai.openai.endPoint.embeddings.resp.EmbeddingCompletionResponse;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;

/**
 * @Description: OpenAI 嵌入类会话
 **/
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class DefaultEmbeddingSession extends Session implements EmbeddingSession {

    public DefaultEmbeddingSession(Configuration configuration) {
        this.setConfiguration(ensureNotNull(configuration, "configuration"));
        this.setOpenaiApiServer(ensureNotNull(configuration.getOpenaiApiServer(), "openaiApiServer"));
    }

    @Override
    public EmbeddingCompletionResponse embeddingCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, List<String> inputList) {
        return this.embeddingCompletions(apiHostByUser, apiKeyByUser, apiUrlByUser, EmbeddingCompletionRequest.builder().input(inputList).build());
    }

    @Override
    public EmbeddingCompletionResponse embeddingCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String input) {
        return this.embeddingCompletions(apiHostByUser, apiKeyByUser, apiUrlByUser, EmbeddingCompletionRequest.builder().input(Arrays.asList(input)).build());
    }

    @Override
    public EmbeddingCompletionResponse embeddingCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, EmbeddingCompletionRequest embeddingCompletionRequest) {
        EmbeddingCompletionResponse response = this.getOpenaiApiServer().createEmbeddingsCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, embeddingCompletionRequest).blockingGet();
        List<EmbeddingObject> data = response.getData();
        List<String> input = embeddingCompletionRequest.getInput();
        // 将文本和结果进行对应
        IntStream.range(0, Math.min(data.size(), input.size()))
                .forEach(i -> data.get(i).setContent(input.get(i)));
        return response;
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultFilesSession.java
================================================
package com.ai.openai.achieve.defaults.session;

import com.ai.openai.achieve.Configuration;
import com.ai.openai.achieve.standard.session.FilesSession;
import com.ai.openai.endPoint.files.FileObject;
import com.ai.openai.endPoint.files.resp.DeleteFileResponse;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;

import java.io.File;
import java.util.List;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;

/**
 * @Description: OpenAI 文件类会话
 **/
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class DefaultFilesSession extends Session implements FilesSession {

    public DefaultFilesSession(Configuration configuration) {
        this.setConfiguration(ensureNotNull(configuration, "configuration"));
        this.setOpenaiApiServer(ensureNotNull(configuration.getOpenaiApiServer(), "openaiApiServer"));
    }

    @Override
    public List<FileObject> listFilesCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser) {
        return this.getOpenaiApiServer().listFilesCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser).blockingGet().getData();
    }

    @Override
    public FileObject uploadFileCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, File file, String purpose) {
        RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", file.getName(), fileBody);
        RequestBody purposeBody = RequestBody.create(MediaType.parse("multipart/form-data"), purpose);
        return this.getOpenaiApiServer().uploadFileCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, multipartBody, purposeBody).blockingGet();
    }

    @Override
    public DeleteFileResponse deleteFileCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String fileId) {
        return this.getOpenaiApiServer().deleteFileCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, fileId).blockingGet();
    }

    @Override
    public FileObject retrieveFileCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String fileId) {
        return this.getOpenaiApiServer().retrieveFileCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, fileId).blockingGet();
    }

    @Override
    public ResponseBody retrieveFileContextCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String fileId) {
        return this.getOpenaiApiServer().retrieveFileContentCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, fileId).blockingGet();
    }


}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultFineTuningSession.java
================================================
package com.ai.openai.achieve.defaults.session;

import com.ai.openai.achieve.Configuration;
import com.ai.openai.achieve.standard.session.FineTuningSession;
import com.ai.openai.common.CommonListResponse;
import com.ai.openai.endPoint.fineTuning.FineTuningEvent;
import com.ai.openai.endPoint.fineTuning.req.FineTuningRequest;
import com.ai.openai.endPoint.fineTuning.req.ListFineTuningRequest;
import com.ai.openai.endPoint.fineTuning.resp.FineTuningResponse;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;

/**
 * @Description: OpenAI 微调类会话
 **/
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class DefaultFineTuningSession extends Session implements FineTuningSession {

    public DefaultFineTuningSession(Configuration configuration) {
        this.setConfiguration(ensureNotNull(configuration, "configuration"));
        this.setOpenaiApiServer(ensureNotNull(configuration.getOpenaiApiServer(), "openaiApiServer"));
    }

    @Override
    public FineTuningResponse createFineTuningJobCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, FineTuningRequest fineTuningRequest) {
        return this.getOpenaiApiServer().createFineTuningJobCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, fineTuningRequest).blockingGet();
    }

    @Override
    public CommonListResponse<FineTuningResponse> listFineTuningJobsCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, ListFineTuningRequest listFineTuningRequest) {
        return this.listFineTuningJobsCompletions(apiHostByUser, apiKeyByUser, apiUrlByUser, listFineTuningRequest.getAfter(), listFineTuningRequest.getLimit());
    }

    @Override
    public CommonListResponse<FineTuningResponse> listFineTuningJobsCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String after, Integer limit) {
        return this.getOpenaiApiServer().listFineTuningJobsCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, after, limit).blockingGet();
    }

    @Override
    public FineTuningResponse retrieveFineTuningJobCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String fineTuningJobId) {
        return this.getOpenaiApiServer().retrieveFineTuningJobCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, fineTuningJobId).blockingGet();
    }

    @Override
    public FineTuningResponse cancelFineTuningJobCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String fineTuningJobId) {
        return this.getOpenaiApiServer().cancelFineTuningJobCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, fineTuningJobId).blockingGet();
    }

    @Override
    public CommonListResponse<FineTuningEvent> listFineTuningEventsCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String fineTuningJobId) {
        return this.getOpenaiApiServer().listFineTuningEventsCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, fineTuningJobId).blockingGet();
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultImageSession.java
================================================
package com.ai.openai.achieve.defaults.session;

import com.ai.openai.achieve.Configuration;
import com.ai.openai.achieve.standard.session.ImageSession;
import com.ai.openai.endPoint.images.ImageObject;
import com.ai.openai.endPoint.images.req.CreateImageRequest;
import com.ai.openai.endPoint.images.req.ImageEditRequest;
import com.ai.openai.endPoint.images.req.ImageVariationRequest;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;

/**
 * @Description: OpenAI 图片类会话
 **/
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class DefaultImageSession extends Session implements ImageSession {

    public DefaultImageSession(Configuration configuration) {
        this.setConfiguration(ensureNotNull(configuration, "configuration"));
        this.setOpenaiApiServer(ensureNotNull(configuration.getOpenaiApiServer(), "openaiApiServer"));
    }

    @Override
    public List<ImageObject> createImageCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, CreateImageRequest createImageRequest) {
        return this.getOpenaiApiServer().createImageCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, createImageRequest).blockingGet().getData();
    }

    @Override
    public List<ImageObject> editImageCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, File image, File mask, ImageEditRequest imageEditRequest) {
        // 创建 RequestBody,用于封装构建RequestBody
        RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), image);
        MultipartBody.Part imageMultipartBody = MultipartBody.Part.createFormData("image", image.getName(), imageBody);
        MultipartBody.Part maskMultipartBody = null;
        if (Objects.nonNull(mask)) {
            RequestBody maskBody = RequestBody.create(MediaType.parse("multipart/form-data"), mask);
            maskMultipartBody = MultipartBody.Part.createFormData("mask", image.getName(), maskBody);
        }
        Map<String, RequestBody> requestBodyMap = new HashMap<>();
        requestBodyMap.put("prompt", RequestBody.create(MediaType.parse("multipart/form-data"), imageEditRequest.getPrompt()));
        requestBodyMap.put("n", RequestBody.create(MediaType.parse("multipart/form-data"), imageEditRequest.getN().toString()));
        requestBodyMap.put("size", RequestBody.create(MediaType.parse("multipart/form-data"), imageEditRequest.getSize()));
        requestBodyMap.put("response_format", RequestBody.create(MediaType.parse("multipart/form-data"), imageEditRequest.getResponseFormat()));
        if (!(Objects.isNull(imageEditRequest.getUser()) || "".equals(imageEditRequest.getUser()))) {
            requestBodyMap.put("user", RequestBody.create(MediaType.parse("multipart/form-data"), imageEditRequest.getUser()));
        }
        return this.getOpenaiApiServer().editImageCompletion(
                apiHostByUser, apiKeyByUser, apiUrlByUser,
                imageMultipartBody,
                maskMultipartBody,
                requestBodyMap
        ).blockingGet().getData();
    }

    @Override
    public List<ImageObject> variationImageCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, File image, ImageVariationRequest imageVariationRequest) {
        RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), image);
        MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("image", image.getName(), imageBody);
        Map<String, RequestBody> requestBodyMap = new HashMap<>();
        requestBodyMap.put("n", RequestBody.create(MediaType.parse("multipart/form-data"), imageVariationRequest.getN().toString()));
        requestBodyMap.put("size", RequestBody.create(MediaType.parse("multipart/form-data"), imageVariationRequest.getSize()));
        requestBodyMap.put("response_format", RequestBody.create(MediaType.parse("multipart/form-data"), imageVariationRequest.getResponseFormat()));
        if (!(Objects.isNull(imageVariationRequest.getUser()) || "".equals(imageVariationRequest.getUser()))) {
            requestBodyMap.put("user", RequestBody.create(MediaType.parse("multipart/form-data"), imageVariationRequest.getUser()));
        }
        return this.getOpenaiApiServer().variationImageCompletion(
                apiHostByUser, apiKeyByUser, apiUrlByUser,
                multipartBody,
                requestBodyMap
        ).blockingGet().getData();
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultModelSession.java
================================================
package com.ai.openai.achieve.defaults.session;


import com.ai.openai.achieve.Configuration;
import com.ai.openai.achieve.standard.session.ModelSession;
import com.ai.openai.endPoint.models.ModelObject;
import com.ai.openai.endPoint.models.resp.DeleteFineTuneModelResponse;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.util.List;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;

/**
 * @Description: OpenAI 模型类会话
 **/
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class DefaultModelSession extends Session implements ModelSession {

    public DefaultModelSession(Configuration configuration) {
        this.setConfiguration(ensureNotNull(configuration, "configuration"));
        this.setOpenaiApiServer(ensureNotNull(configuration.getOpenaiApiServer(), "openaiApiServer"));
    }

    @Override
    public List<ModelObject> listModelCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser) {
        return this.getOpenaiApiServer().listModelsCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser).blockingGet().getData();
    }

    @Override
    public ModelObject retrieveModelCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String model) {
        return this.getOpenaiApiServer().retrieveModelCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, model).blockingGet();
    }

    @Override
    public DeleteFineTuneModelResponse deleteFineTuneModelCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String model) {
        return this.getOpenaiApiServer().deleteFineTuneModelCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, model).blockingGet();
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultModerationSession.java
================================================
package com.ai.openai.achieve.defaults.session;


import com.ai.openai.achieve.Configuration;
import com.ai.openai.achieve.standard.session.ModerationSession;
import com.ai.openai.endPoint.moderations.Result;
import com.ai.openai.endPoint.moderations.req.ModerationRequest;
import com.ai.openai.endPoint.moderations.resp.ModerationResponse;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.util.List;
import java.util.stream.IntStream;

import static com.ai.common.utils.ValidationUtils.ensureNotNull;

/**
 * @Description: OpenAI 审核类会话
 **/
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class DefaultModerationSession extends Session implements ModerationSession {

    public DefaultModerationSession(Configuration configuration) {
        this.setConfiguration(ensureNotNull(configuration, "configuration"));
        this.setOpenaiApiServer(ensureNotNull(configuration.getOpenaiApiServer(), "openaiApiServer"));
    }

    @Override
    public ModerationResponse moderationCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, ModerationRequest moderationRequest) {
        ModerationResponse response = getOpenaiApiServer().moderationCompletion(apiHostByUser, apiKeyByUser, apiUrlByUser, moderationRequest).blockingGet();
        List<String> inputs = moderationRequest.getInput();
        List<Result> results = response.getResults();
        // 将审核文本和审核结果进行对应
        IntStream.range(0, Math.min(results.size(), inputs.size()))
                .forEach(i -> results.get(i).setContent(inputs.get(i)));
        return response;
    }
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/Session.java
================================================
package com.ai.openai.achieve.defaults.session;

import com.ai.openai.achieve.Configuration;
import com.ai.openai.achieve.standard.api.OpenaiApiServer;
import lombok.Data;


@Data
public class Session {

    /**
     * 配置信息
     */
    private Configuration configuration;
    /**
     * OpenAI 接口
     */
    private OpenaiApiServer openaiApiServer;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/api/OpenaiApiServer.java
================================================
package com.ai.openai.achieve.standard.api;

import com.ai.openai.common.CommonListResponse;
import com.ai.openai.endPoint.audio.req.TtsCompletionRequest;
import com.ai.openai.endPoint.audio.resp.SttCompletionResponse;
import com.ai.openai.endPoint.chat.req.DefaultChatCompletionRequest;
import com.ai.openai.endPoint.chat.req.FuncChatCompletionRequest;
import com.ai.openai.endPoint.chat.req.ImgChatCompletionRequest;
import com.ai.openai.endPoint.chat.req.QaCompletionRequest;
import com.ai.openai.endPoint.chat.resp.ChatCompletionResponse;
import com.ai.openai.endPoint.chat.resp.QaCompletionResponse;
import com.ai.openai.endPoint.embeddings.req.EmbeddingCompletionRequest;
import com.ai.openai.endPoint.embeddings.resp.EmbeddingCompletionResponse;
import com.ai.openai.endPoint.files.FileObject;
import com.ai.openai.endPoint.files.resp.DeleteFileResponse;
import com.ai.openai.endPoint.fineTuning.FineTuningEvent;
import com.ai.openai.endPoint.fineTuning.req.FineTuningRequest;
import com.ai.openai.endPoint.fineTuning.resp.FineTuningResponse;
import com.ai.openai.endPoint.images.req.CreateImageRequest;
import com.ai.openai.endPoint.images.resp.CreateImageResponse;
import com.ai.openai.endPoint.models.ModelObject;
import com.ai.openai.endPoint.models.resp.DeleteFineTuneModelResponse;
import com.ai.openai.endPoint.moderations.req.ModerationRequest;
import com.ai.openai.endPoint.moderations.resp.ModerationResponse;
import io.reactivex.Single;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.*;

import java.util.Map;

import static com.ai.core.exception.Constants.*;

/**
 * @Description: OpenAI API接口
 **/
public interface OpenaiApiServer {

    /**
     * 简单问答接口
     *
     * @param apiHostByUser       用户自定义 host
     * @param apiKeyByUser        用户自定义密钥
     * @param apiUrlByUser        用户自定义请求地址
     * @param qaCompletionRequest 用户自定义封装的请求参数
     * @return 请求结果
     */
    @POST("/v1/completions")
    Single<QaCompletionResponse> createQaCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Body QaCompletionRequest qaCompletionRequest);

    /**
     * 普通对话聊天接口
     *
     * @param apiHostByUser                用户自定义 host
     * @param apiKeyByUser                 用户自定义密钥
     * @param apiUrlByUser                 用户自定义请求地址
     * @param defaultChatCompletionRequest 用户自定义封装的请求参数
     * @return 请求结果
     */
    @POST("/v1/chat/completions")
    Single<ChatCompletionResponse> createChatCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Body DefaultChatCompletionRequest defaultChatCompletionRequest);

    /**
     * 图片对话聊天接口
     *
     * @param apiHostByUser            用户自定义 host
     * @param apiKeyByUser             用户自定义密钥
     * @param apiUrlByUser             用户自定义请求地址
     * @param imgChatCompletionRequest 用户自定义封装的请求参数
     * @return 请求结果
     */
    @POST("/v1/chat/completions")
    Single<ChatCompletionResponse> createChatCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Body ImgChatCompletionRequest imgChatCompletionRequest);

    /**
     * 函数对话聊天接口
     *
     * @param apiHostByUser             用户自定义 host
     * @param apiKeyByUser              用户自定义密钥
     * @param apiUrlByUser              用户自定义请求地址
     * @param funcChatCompletionRequest 用户自定义封装的请求参数
     * @return 请求结果
     */
    @POST("/v1/chat/completions")
    Single<ChatCompletionResponse> createChatCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Body FuncChatCompletionRequest funcChatCompletionRequest);


    /**
     * 输入文本生成音频
     *
     * @param apiHostByUser        用户自定义 host
     * @param apiKeyByUser         用户自定义密钥
     * @param apiUrlByUser         用户自定义请求地址
     * @param ttsCompletionRequest 用户自定义封装的请求参数
     * @return 请求结果
     */
    @POST("/v1/audio/speech")
    @Streaming
    Call<ResponseBody> createSpeechCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Body TtsCompletionRequest ttsCompletionRequest);

    /**
     * 发送音频文件,解析成文本
     *
     * @param apiHostByUser  用户自定义 host
     * @param apiKeyByUser   用户自定义密钥
     * @param apiUrlByUser   用户自定义请求地址
     * @param file           音频文件
     * @param requestBodyMap 请求参数
     * @return 请求结果
     */
    @Multipart
    @POST("/v1/audio/transcriptions")
    Single<SttCompletionResponse> createTranscriptionCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Part MultipartBody.Part file, @PartMap Map<String, RequestBody> requestBodyMap);

    /**
     * 发送音频文件,解析并翻译为英文
     *
     * @param apiHostByUser  用户自定义 host
     * @param apiKeyByUser   用户自定义密钥
     * @param apiUrlByUser   用户自定义请求地址
     * @param file           音频文件
     * @param requestBodyMap 请求参数
     * @return 请求结果
     */
    @Multipart
    @POST("/v1/audio/translations")
    Single<SttCompletionResponse> createTranslationCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Part MultipartBody.Part file, @PartMap() Map<String, RequestBody> requestBodyMap);

    /**
     * 创建嵌入
     *
     * @param apiHostByUser              用户自定义 host
     * @param apiKeyByUser               用户自定义密钥
     * @param apiUrlByUser               用户自定义请求地址
     * @param embeddingCompletionRequest 请求参数
     * @return 请求结果
     */
    @POST("/v1/embeddings")
    Single<EmbeddingCompletionResponse> createEmbeddingsCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Body EmbeddingCompletionRequest embeddingCompletionRequest);

    /**
     * 创建微调作业
     *
     * @param apiHostByUser     用户自定义 host
     * @param apiKeyByUser      用户自定义密钥
     * @param apiUrlByUser      用户自定义请求地址
     * @param fineTuningRequest 请求参数
     * @return 请求结果
     */
    @POST("/v1/fine_tuning/jobs")
    Single<FineTuningResponse> createFineTuningJobCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Body FineTuningRequest fineTuningRequest);

    /**
     * 列出微调作业
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param after         上一个分页请求中最后一个作业的标识符
     * @param limit         要检索的微调作业数
     * @return 请求结果
     */
    @GET("/v1/fine_tuning/jobs")
    Single<CommonListResponse<FineTuningResponse>> listFineTuningJobsCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Query("after") String after, @Query("limit") Integer limit);

    /**
     * 检索微调作业
     *
     * @param apiHostByUser   用户自定义 host
     * @param apiKeyByUser    用户自定义密钥
     * @param apiUrlByUser    用户自定义请求地址
     * @param fineTuningJobId 微调作业的 ID
     * @return 请求结果
     */
    @GET("/v1/fine_tuning/jobs/{fine_tuning_job_id}")
    Single<FineTuningResponse> retrieveFineTuningJobCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Path("fine_tuning_job_id") String fineTuningJobId);

    /**
     * 取消微调作业
     *
     * @param apiHostByUser   用户自定义 host
     * @param apiKeyByUser    用户自定义密钥
     * @param apiUrlByUser    用户自定义请求地址
     * @param fineTuningJobId 微调作业的 ID
     * @return 请求结果
     */
    @POST("/v1/fine_tuning/jobs/{fine_tuning_job_id}/cancel")
    Single<FineTuningResponse> cancelFineTuningJobCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Path("fine_tuning_job_id") String fineTuningJobId);

    /**
     * 列出微调事件
     *
     * @param apiHostByUser   用户自定义 host
     * @param apiKeyByUser    用户自定义密钥
     * @param apiUrlByUser    用户自定义请求地址
     * @param fineTuningJobId 微调作业的 ID
     * @return 请求结果
     */
    @GET("/v1/fine_tuning/jobs/{fine_tuning_job_id}/events")
    Single<CommonListResponse<FineTuningEvent>> listFineTuningEventsCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Path("fine_tuning_job_id") String fineTuningJobId);

    /**
     * 返回属于用户组织的文件列表
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @return 文件列表
     */
    @GET("/v1/files")
    Single<CommonListResponse<FileObject>> listFilesCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser);

    /**
     * 上传文件
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param file          要上载的 File 对象(不是文件名)
     * @param purpose       上传文件的预期用途
     * @return 上载的 File 对象
     */
    @Multipart
    @POST("/v1/files")
    Single<FileObject> uploadFileCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Part MultipartBody.Part file, @Part("purpose") RequestBody purpose);

    /**
     * 删除文件
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param fileId        文件ID
     * @return 删除状态
     */
    @DELETE("/v1/files/{file_id}")
    Single<DeleteFileResponse> deleteFileCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Path("file_id") String fileId);

    /**
     * 检索文件
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param fileId        文件ID
     * @return 文件信息
     */
    @GET("/v1/files/{file_id}")
    Single<FileObject> retrieveFileCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Path("file_id") String fileId);


    /**
     * 获取文件内容
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param fileId        文件ID
     * @return 文件内容
     */
    @Streaming
    @GET("/v1/files/{file_id}/content")
    Single<ResponseBody> retrieveFileContentCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Path("file_id") String fileId);

    /**
     * 生成图片
     *
     * @param apiHostByUser      用户自定义 host
     * @param apiKeyByUser       用户自定义密钥
     * @param apiUrlByUser       用户自定义请求地址
     * @param createImageRequest 生成图片的请求参数
     * @return 图片信息
     */
    @POST("/v1/images/generations")
    Single<CreateImageResponse> createImageCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Body CreateImageRequest createImageRequest);

    /**
     * 编辑图片
     *
     * @param apiHostByUser  用户自定义 host
     * @param apiKeyByUser   用户自定义密钥
     * @param apiUrlByUser   用户自定义请求地址
     * @param image          被编辑的图片
     * @param mask           一个额外的图像,其完全透明的区域(例如,alpha为零)指示应该编辑的位置。必须是有效的 PNG 文件,小于 4MB,并且尺寸与image相同。
     * @param requestBodyMap 请求参数
     * @return 图片信息
     */
    @Multipart
    @POST("/v1/images/edits")
    Single<CreateImageResponse> editImageCompletion(@Header(API_HOST) String apiHostByUser,
                                                    @Header(API_KEY) String apiKeyByUser,
                                                    @Header(URL) String apiUrlByUser,
                                                    @Part() MultipartBody.Part image, @Part() MultipartBody.Part mask, @PartMap() Map<String, RequestBody> requestBodyMap);

    /**
     * 创建给定图像的变体
     *
     * @param apiHostByUser  用户自定义 host
     * @param apiKeyByUser   用户自定义密钥
     * @param apiUrlByUser   用户自定义请求地址
     * @param image          被编辑的图片
     * @param requestBodyMap 请求参数
     * @return 图片信息
     */
    @Multipart
    @POST("/v1/images/variations")
    Single<CreateImageResponse> variationImageCompletion(@Header(API_HOST) String apiHostByUser,
                                                         @Header(API_KEY) String apiKeyByUser,
                                                         @Header(URL) String apiUrlByUser, @Part() MultipartBody.Part image,
                                                         @PartMap() Map<String, RequestBody> requestBodyMap);

    /**
     * 列出模型
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @return 模型信息
     */
    @GET("/v1/models")
    Single<CommonListResponse<ModelObject>> listModelsCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser);

    /**
     * 检索模型信息
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param model         模型ID
     * @return 模型信息
     */
    @GET("/v1/models/{model}")
    Single<ModelObject> retrieveModelCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Path("model") String model);

    /**
     * 删除微调模型
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param model         模型ID
     * @return 删除状态
     */
    @DELETE("/v1/models/{model}")
    Single<DeleteFineTuneModelResponse> deleteFineTuneModelCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Path("model") String model);


    /**
     * 审核
     *
     * @param apiHostByUser     用户自定义 host
     * @param apiKeyByUser      用户自定义密钥
     * @param apiUrlByUser      用户自定义请求地址
     * @param moderationRequest 审核请求参数
     * @return 审核结果
     */
    @POST("/v1/moderations")
    Single<ModerationResponse> moderationCompletion(@Header(API_HOST) String apiHostByUser, @Header(API_KEY) String apiKeyByUser, @Header(URL) String apiUrlByUser, @Body ModerationRequest moderationRequest);


}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/AggregationSession.java
================================================
package com.ai.openai.achieve.standard.session;

/**
 * @Description: 聚合各大场景的session
 **/
public interface AggregationSession {

    /**
     * 获取音频会话窗口
     */
    AudioSession getAudioSession();

    /**
     * 获取对话会话窗口
     */
    ChatSession getChatSession();

    /**
     * 获取微调会话窗口
     */
    FineTuningSession getFineTuningSession();

    /**
     * 获取嵌入会话窗口
     */
    EmbeddingSession getEmbeddingSession();

    /**
     * 获取文件会话窗口
     */
    FilesSession getFilesSession();

    /**
     * 获取图片会话窗口
     */
    ImageSession getImageSession();

    /**
     * 获取模型会话窗口
     */
    ModelSession getModelSession();

    /**
     * 获取审核会话窗口
     */
    ModerationSession getModerationSession();

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/AudioSession.java
================================================
package com.ai.openai.achieve.standard.session;

import com.ai.openai.endPoint.audio.req.SttCompletionRequest;
import com.ai.openai.endPoint.audio.req.TtsCompletionRequest;
import com.ai.openai.endPoint.audio.resp.SttCompletionResponse;
import retrofit2.Callback;

/**
 * @Description: openAi 音频会话窗口
 **/
public interface AudioSession {

    /**
     * 文字转语音
     *
     * @param apiHostByUser        用户自定义 host
     * @param apiKeyByUser         用户自定义密钥
     * @param apiUrlByUser         用户自定义请求地址
     * @param ttsCompletionRequest 语音接口请求参数
     * @param callback             回调函数
     */
    void ttsCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, TtsCompletionRequest ttsCompletionRequest, Callback callback);

    /**
     * 语音转文字
     *
     * @param apiHostByUser        用户自定义 host
     * @param apiKeyByUser         用户自定义密钥
     * @param apiUrlByUser         用户自定义请求地址
     * @param sttCompletionRequest 音频转文字接口请求参数
     * @return 请求结果
     */
    SttCompletionResponse sttCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, SttCompletionRequest sttCompletionRequest);

    /**
     * 翻译
     *
     * @param apiHostByUser        用户自定义 host
     * @param apiKeyByUser         用户自定义密钥
     * @param apiUrlByUser         用户自定义请求地址
     * @param sttCompletionRequest 音频转文字接口请求参数
     * @return 请求结果
     */
    SttCompletionResponse translationCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, SttCompletionRequest sttCompletionRequest);
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/ChatSession.java
================================================
package com.ai.openai.achieve.standard.session;

import com.ai.openai.endPoint.chat.req.DefaultChatCompletionRequest;
import com.ai.openai.endPoint.chat.req.FuncChatCompletionRequest;
import com.ai.openai.endPoint.chat.req.ImgChatCompletionRequest;
import com.ai.openai.endPoint.chat.req.QaCompletionRequest;
import com.ai.openai.endPoint.chat.resp.ChatCompletionResponse;
import com.ai.openai.endPoint.chat.resp.QaCompletionResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;

import java.util.concurrent.CompletableFuture;

/**
 * @description openAi 聊天会话窗口
 */
public interface ChatSession {

    /**
     * 简单问答
     *
     * @param apiHostByUser       用户自定义 host
     * @param apiKeyByUser        用户自定义密钥
     * @param apiUrlByUser        用户自定义请求地址
     * @param qaCompletionRequest 用户自定义封装的请求参数
     * @return 请求结果
     */
    QaCompletionResponse qaCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, QaCompletionRequest qaCompletionRequest);

    /**
     * 简单问答,流式返回。
     *
     * @param apiHostByUser       用户自定义 host
     * @param apiKeyByUser        用户自定义密钥
     * @param apiUrlByUser        用户自定义请求地址
     * @param qaCompletionRequest 用户自定义封装的请求参数
     * @param eventSourceListener 事件监听者
     * @return 事件源
     */
    EventSource qaCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, QaCompletionRequest qaCompletionRequest, EventSourceListener eventSourceListener) throws JsonProcessingException;

    /**
     * 普通对话聊天
     *
     * @param apiHostByUser                用户自定义 host
     * @param apiKeyByUser                 用户自定义密钥
     * @param apiUrlByUser                 用户自定义请求地址
     * @param defaultChatCompletionRequest 用户自定义封装的请求参数
     * @return 请求结果
     */
    ChatCompletionResponse chatCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, DefaultChatCompletionRequest defaultChatCompletionRequest);

    /**
     * 图片对话聊天
     *
     * @param apiHostByUser            用户自定义 host
     * @param apiKeyByUser             用户自定义密钥
     * @param apiUrlByUser             用户自定义请求地址
     * @param imgChatCompletionRequest 用户自定义封装的请求参数
     * @return 请求结果
     */
    ChatCompletionResponse chatCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, ImgChatCompletionRequest imgChatCompletionRequest);

    /**
     * 函数对话聊天
     *
     * @param apiHostByUser             用户自定义 host
     * @param apiKeyByUser              用户自定义密钥
     * @param apiUrlByUser              用户自定义请求地址
     * @param funcChatCompletionRequest 用户自定义封装的请求参数
     * @return 请求结果
     */
    ChatCompletionResponse chatCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, FuncChatCompletionRequest funcChatCompletionRequest);

    /**
     * 对话聊天,流式返回,此函数为对话聊天流式返回的基础函数。
     *
     * @param apiHostByUser                用户自定义 host
     * @param apiKeyByUser                 用户自定义密钥
     * @param apiUrlByUser                 用户自定义请求地址
     * @param defaultChatCompletionRequest 用户自定义封装的请求参数
     * @param eventSourceListener          事件监听者
     * @return 事件源
     */
    EventSource chatCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, DefaultChatCompletionRequest defaultChatCompletionRequest, EventSourceListener eventSourceListener) throws JsonProcessingException;

    /**
     * 对话聊天 & 流式反馈 & 一次反馈
     *
     * @param defaultChatCompletionRequest 请求信息
     * @return 应答结果
     */
    CompletableFuture<String> chatCompletionsFuture(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, DefaultChatCompletionRequest defaultChatCompletionRequest) throws InterruptedException, JsonProcessingException;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/EmbeddingSession.java
================================================
package com.ai.openai.achieve.standard.session;

import com.ai.openai.endPoint.embeddings.req.EmbeddingCompletionRequest;
import com.ai.openai.endPoint.embeddings.resp.EmbeddingCompletionResponse;

import java.util.List;

/**
 * @Description: 嵌入会话窗口
 **/
public interface EmbeddingSession {

    /**
     * 嵌入
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param inputList     文本数组
     * @return 请求结果
     */
    EmbeddingCompletionResponse embeddingCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, List<String> inputList);

    /**
     * 嵌入
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param input         文本
     * @return 请求结果
     */
    EmbeddingCompletionResponse embeddingCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String input);

    /**
     * 嵌入
     *
     * @param apiHostByUser              用户自定义 host
     * @param apiKeyByUser               用户自定义密钥
     * @param apiUrlByUser               用户自定义请求地址
     * @param embeddingCompletionRequest 请求参数
     * @return 请求结果
     */
    EmbeddingCompletionResponse embeddingCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, EmbeddingCompletionRequest embeddingCompletionRequest);
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/FilesSession.java
================================================
package com.ai.openai.achieve.standard.session;

import com.ai.openai.endPoint.files.FileObject;
import com.ai.openai.endPoint.files.resp.DeleteFileResponse;
import okhttp3.ResponseBody;

import java.io.File;
import java.util.List;

/**
 * @Description: 文件会话窗口
 **/
public interface FilesSession {
    /**
     * 返回属于用户组织的文件列表
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @return 文件列表
     */
    List<FileObject> listFilesCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser);

    /**
     * 上传文件
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param file          需要上传的文件
     * @param purpose       上传文件的用途
     * @return 文件信息
     */
    FileObject uploadFileCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, File file, String purpose);

    /**
     * 删除文件
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param fileId        文件ID
     * @return 删除状态信息
     */
    DeleteFileResponse deleteFileCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String fileId);

    /**
     * 检索文件
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param fileId        文件ID
     * @return 文件信息
     */
    FileObject retrieveFileCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String fileId);

    /**
     * 获取文件内容
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param fileId        文件ID
     * @return 返回结果
     */
    ResponseBody retrieveFileContextCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String fileId);
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/FineTuningSession.java
================================================
package com.ai.openai.achieve.standard.session;

import com.ai.openai.common.CommonListResponse;
import com.ai.openai.endPoint.fineTuning.FineTuningEvent;
import com.ai.openai.endPoint.fineTuning.req.FineTuningRequest;
import com.ai.openai.endPoint.fineTuning.req.ListFineTuningRequest;
import com.ai.openai.endPoint.fineTuning.resp.FineTuningResponse;

/**
 * @Description: 微调会话窗口
 **/
public interface FineTuningSession {

    /**
     * 创建微调作业
     *
     * @param apiHostByUser     用户自定义 host
     * @param apiKeyByUser      用户自定义密钥
     * @param apiUrlByUser      用户自定义请求地址
     * @param fineTuningRequest 请求参数
     * @return 请求结果
     */
    FineTuningResponse createFineTuningJobCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, FineTuningRequest fineTuningRequest);

    /**
     * 列出微调作业
     *
     * @param apiHostByUser         用户自定义 host
     * @param apiKeyByUser          用户自定义密钥
     * @param apiUrlByUser          用户自定义请求地址
     * @param listFineTuningRequest 请求参数
     * @return 请求结果
     */
    CommonListResponse<FineTuningResponse> listFineTuningJobsCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, ListFineTuningRequest listFineTuningRequest);

    /**
     * 列出微调作业
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param after         上一个分页请求中最后一个作业的标识符
     * @param limit         要检索的微调作业数
     * @return 请求结果
     */
    CommonListResponse<FineTuningResponse> listFineTuningJobsCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String after, Integer limit);

    /**
     * 检索微调作业
     *
     * @param apiHostByUser   用户自定义 host
     * @param apiKeyByUser    用户自定义密钥
     * @param apiUrlByUser    用户自定义请求地址
     * @param fineTuningJobId 微调作业的 ID
     * @return 请求结果
     */
    FineTuningResponse retrieveFineTuningJobCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String fineTuningJobId);

    /**
     * 取消微调作业
     *
     * @param apiHostByUser   用户自定义 host
     * @param apiKeyByUser    用户自定义密钥
     * @param apiUrlByUser    用户自定义请求地址
     * @param fineTuningJobId 微调作业的 ID
     * @return 请求结果
     */
    FineTuningResponse cancelFineTuningJobCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String fineTuningJobId);

    /**
     * 列出微调事件
     *
     * @param apiHostByUser   用户自定义 host
     * @param apiKeyByUser    用户自定义密钥
     * @param apiUrlByUser    用户自定义请求地址
     * @param fineTuningJobId 微调作业的 ID
     * @return 请求结果
     */
    CommonListResponse<FineTuningEvent> listFineTuningEventsCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String fineTuningJobId);
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/ImageSession.java
================================================
package com.ai.openai.achieve.standard.session;

import com.ai.openai.endPoint.images.ImageObject;
import com.ai.openai.endPoint.images.req.CreateImageRequest;
import com.ai.openai.endPoint.images.req.ImageEditRequest;
import com.ai.openai.endPoint.images.req.ImageVariationRequest;

import java.io.File;
import java.util.List;

/**
 * @Description: 图片会话窗口
 **/
public interface ImageSession {

    /**
     * @param apiHostByUser      用户自定义 host
     * @param apiKeyByUser       用户自定义密钥
     * @param apiUrlByUser       用户自定义请求地址
     * @param createImageRequest 请求参数
     * @return 图片信息
     */
    List<ImageObject> createImageCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, CreateImageRequest createImageRequest);

    /**
     * 编辑图像
     *
     * @param apiHostByUser    用户自定义 host
     * @param apiKeyByUser     用户自定义密钥
     * @param apiUrlByUser     用户自定义请求地址
     * @param image            要编辑的图像
     * @param mask             一个额外的图像,其完全透明的区域(例如,alpha为零)指示应该编辑的位置。必须是有效的 PNG 文件,小于 4MB,并且尺寸与image相同
     * @param imageEditRequest 请求参数
     * @return 图片信息
     */
    List<ImageObject> editImageCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, File image, File mask, ImageEditRequest imageEditRequest);

    /**
     * 创建图像变体
     *
     * @param apiHostByUser         用户自定义 host
     * @param apiKeyByUser          用户自定义密钥
     * @param apiUrlByUser          用户自定义请求地址
     * @param image                 要编辑的图像
     * @param imageVariationRequest 请求参数
     * @return 图片信息
     */
    List<ImageObject> variationImageCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, File image, ImageVariationRequest imageVariationRequest);
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/ModelSession.java
================================================
package com.ai.openai.achieve.standard.session;


import com.ai.openai.endPoint.models.ModelObject;
import com.ai.openai.endPoint.models.resp.DeleteFineTuneModelResponse;

import java.util.List;

/**
 * @Description: 模型会话窗口
 **/
public interface ModelSession {

    /**
     * 列出模型
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @return 模型列表
     */
    List<ModelObject> listModelCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser);

    /**
     * 检索模型
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param model         模型ID
     * @return 模型信息
     */
    ModelObject retrieveModelCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String model);

    /**
     * 删除微调模型
     *
     * @param apiHostByUser 用户自定义 host
     * @param apiKeyByUser  用户自定义密钥
     * @param apiUrlByUser  用户自定义请求地址
     * @param model         模型ID
     * @return 删除状态
     */
    DeleteFineTuneModelResponse deleteFineTuneModelCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, String model);
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/ModerationSession.java
================================================
package com.ai.openai.achieve.standard.session;


import com.ai.openai.endPoint.moderations.req.ModerationRequest;
import com.ai.openai.endPoint.moderations.resp.ModerationResponse;

/**
 * @Description: 审核会话窗口
 **/
public interface ModerationSession {
    /**
     * 审核
     *
     * @param apiHostByUser     用户自定义 host
     * @param apiKeyByUser      用户自定义密钥
     * @param apiUrlByUser      用户自定义请求地址
     * @param moderationRequest 请求参数
     * @return 审核结果
     */
    ModerationResponse moderationCompletions(String apiHostByUser, String apiKeyByUser, String apiUrlByUser, ModerationRequest moderationRequest);
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/common/ApiUrl.java
================================================
package com.ai.openai.common;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * 各接口API路径
 */
@Getter
@AllArgsConstructor
public enum ApiUrl {

    v1_completions("/v1/completions"),
    v1_chat_completions("/v1/chat/completions"),
    v1_audio_speech("/v1/audio/speech"),
    v1_audio_transcriptions("/v1/audio/transcriptions"),
    v1_audio_translations("/v1/audio/translations"),
    v1_embeddings("/v1/embeddings"),
    v1_fine_tuning_jobs("/v1/fine_tuning/jobs"),
    v1_fine_tuning_jobs_fine_tuning_job_id("/v1/fine_tuning/jobs/{fine_tuning_job_id}"),
    v1_fine_tuning_jobs_fine_tuning_job_id_cancel("/v1/fine_tuning/jobs/{fine_tuning_job_id}/cancel"),
    v1_fine_tuning_jobs_fine_tuning_job_id_events("/v1/fine_tuning/jobs/{fine_tuning_job_id}/events"),
    ;

    private String url;
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/common/CommonListResponse.java
================================================
package com.ai.openai.common;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
 * @Description: 通用返回类
 **/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonListResponse<T> implements Serializable {
    private String object;
    private List<T> data;
    private Error error;
    @JsonProperty("has_more")
    private Boolean hasMore;

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public class Error {
        private String message;
        private String type;
        private String param;
        private String code;
    }
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/common/Usage.java
================================================
package com.ai.openai.common;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Usage {

    /**
     * 请求消耗的token
     */
    @JsonProperty("prompt_tokens")
    private int promptTokens;

    /**
     * 回答消耗的token
     */
    @JsonProperty("completion_tokens")
    private int completionTokens;

    /**
     * 总共消耗的token
     */
    @JsonProperty("total_tokens")
    private int totalTokens;
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/audio/req/SttCompletionRequest.java
================================================
package com.ai.openai.endPoint.audio.req;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
import lombok.experimental.FieldNameConstants;

import java.io.File;
import java.io.Serializable;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldNameConstants
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SttCompletionRequest implements Serializable {

    /**
     * 要转录的音频文件对象(不是文件名)
     * 采用以下格式之一:flac、mp3、mp4、mpeg、mpga、m4a、ogg、wav 或 webm
     */
    @NonNull
    private File file;

    /**
     * 使用的模型名
     */
    @NonNull
    @Builder.Default
    private String model = Model.whisper_1.getModuleName();

    /**
     * 音频的语言,以 ISO-639-1 格式提供输入语言将提高准确性和延迟。
     */
    private String language;

    /**
     * 一个可选文本,用于指导模型的样式或继续上一个音频片段。提示应与音频语言匹配。
     */
    private String prompt;

    /**
     * 脚本输出的格式
     */
    @JsonProperty("response_format")
    private String responseFormat;

    /**
     * 采样温度,介于 0 和 1 之间,默认值为 0 。
     * 较高的值(如 0.8)将使输出更加随机,而较低的值(如 0.2)将使其更具针对性和确定性。
     * 如果设置为 0,模型将使用对数概率自动提高温度,直到达到某些阈值。
     */
    private Double temperature;

    @Getter
    @AllArgsConstructor
    public enum Model {
        whisper_1("whisper-1");
        private String moduleName;
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/audio/req/TtsCompletionRequest.java
================================================
package com.ai.openai.endPoint.audio.req;

import com.ai.openai.endPoint.chat.req.BaseChatCompletionRequest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import java.io.Serializable;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TtsCompletionRequest implements Serializable {

    /**
     * 要使用的模型的 ID
     */
    @Builder.Default
    private String model = BaseChatCompletionRequest.Model.GPT_3_5_TURBO.getModuleName();

    /**
     * 要为其生成音频的文本,最大长度为4096个字符
     */
    @NonNull
    private String input;

    /**
     * 声音样式
     */
    @NonNull
    private String voice;

    /**
     * 音频输入的格式,默认为mp3
     */
    @JsonProperty("response_format")
    private String responseFormat;

    /**
     * 音频的速度,0.25 到 4.0 之中选取一个数,数字越大速度越快。默认为1。
     */
    private String speed;

    /**
     * 构造基础请求内容
     *
     * @param input 文本内容
     * @return 文本转语言请求参数
     */
    public static TtsCompletionRequest baseBuild(String input) {
        return TtsCompletionRequest
                .builder()
                .input(input)
                .voice(Voice.alloy.getVoiceName())
                .model(Model.tts_1.getModuleName())
                .build();
    }

    @Getter
    @AllArgsConstructor
    public enum Model {
        tts_1("tts-1"), tts_1_hd("tts-1-hd");
        private String moduleName;
    }

    /**
     * 声音样式
     */
    @Getter
    @AllArgsConstructor
    public enum Voice {
        alloy("alloy"),
        echo("echo"),
        fable("fable"),
        onyx("onyx"),
        nova("nova"),
        shimmer("shimmer");
        private String voiceName;
    }


}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/audio/resp/SttCompletionResponse.java
================================================
package com.ai.openai.endPoint.audio.resp;


import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SttCompletionResponse implements Serializable {
    /**
     * 转换之后得到的文本
     */
    private String text;
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/ChatChoice.java
================================================
package com.ai.openai.endPoint.chat;

import com.ai.openai.endPoint.chat.msg.DefaultMessage;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @Description: 聊天接口模型返回的信息
 **/
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ChatChoice implements Serializable {

    private long index;

    /**
     * stream = true时,由流式模型响应生成的聊天完成增量
     */
    private DefaultMessage delta;

    /**
     * stream = false时,模型生成的聊天完成消息
     */
    private DefaultMessage message;

    /**
     * 模型停止生成令牌的原因
     */
    @JsonProperty("finish_reason")
    private String finishReason;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/Parameters.java
================================================
package com.ai.openai.endPoint.chat;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Parameters implements Serializable {

    /**
     * 参数类型
     */
    private String type;

    /**
     * 参数属性、描述
     */
    private Object properties;

    /**
     * 方法必输字段
     */
    private List<String> required;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/QaChoice.java
================================================
package com.ai.openai.endPoint.chat;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @Description: 简单问答模型返回的信息
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QaChoice implements Serializable {

    /**
     * 回答内容
     */
    private String text;

    private int index;

    private Object logprobs;

    /**
     * 模型停止生成令牌的原因
     */
    @JsonProperty("finish_reason")
    private String finishReason;
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/ResponseFormat.java
================================================
package com.ai.openai.endPoint.chat;

import lombok.*;

/**
 * @Author: jianglinhong
 * @Description: TODO
 * @DateTime: 2023/12/8 14:22
 **/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ResponseFormat {

    /**
     * 默认:text
     */
    private String type;

    @Getter
    @AllArgsConstructor
    public enum Type {
        JSON_OBJECT("json_object"),
        TEXT("text"),
        ;
        private final String name;
    }
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/BaseMessage.java
================================================
package com.ai.openai.endPoint.chat.msg;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

import java.io.Serializable;

/**
 * @description 基础问答信息
 */
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class BaseMessage implements Serializable {

    /**
     * 角色:system、user、assistant
     */
    private String role;

    private String name;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/Content.java
================================================
package com.ai.openai.endPoint.chat.msg;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

/**
 * @Description: 图片问答信息
 **/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Content {

    /**
     * 输入类型
     */
    private String type;

    /**
     * 问题内容
     */
    private String text;

    /**
     * 图片地址
     */
    @JsonProperty("image_url")
    private ImageUrl imageUrl;

    /**
     * 构建 text 类型的 content
     */
    public static Content BuildTextContent(String text) {
        return Content.builder().type(Type.TEXT.getName()).text(text).build();
    }

    /**
     * 构建 image_url 类型的 content
     */
    public static Content BuildImageUrlContent(String urlOrB64Json) {
        return Content.builder().type(Type.IMAGE_URL.getName()).text(urlOrB64Json).build();
    }

    /**
     * 输入类型
     */
    @Getter
    @AllArgsConstructor
    public enum Type {
        TEXT("text"),
        IMAGE_URL("image_url"),
        ;
        private final String name;
    }
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/DefaultMessage.java
================================================
package com.ai.openai.endPoint.chat.msg;

import com.ai.openai.endPoint.chat.tools.ToolCall;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

import java.io.Serializable;
import java.util.List;

/**
 * @Description: 默认问答内容
 **/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DefaultMessage extends BaseMessage implements Serializable {

    /**
     * 问答内容
     */
    private String content;

    /**
     * 函数式对话时,返回的函数信息
     */
    @JsonProperty("tool_calls")
    private List<ToolCall> toolCalls;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/ImageUrl.java
================================================
package com.ai.openai.endPoint.chat.msg;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Description: 图片问答时,图片的URL
 **/
@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
@AllArgsConstructor
public class ImageUrl {
    /**
     * 图片地址
     */
    private String url;
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/ImgMessage.java
================================================
package com.ai.openai.endPoint.chat.msg;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

import java.io.Serializable;
import java.util.List;

/**
 * @Description: 图片输入
 **/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ImgMessage extends BaseMessage implements Serializable {

    /**
     * 图片对话内容
     */
    private List<Content> content;

    /**
     * 添加类型为 text 的对话内容
     */
    public void addTextContent(String text) {
        addContent(Content.builder().type(Content.Type.TEXT.getName()).text(text).build());
    }

    /**
     * 添加类型为 image_url 的对话内容
     */
    public void addImageContent(String imageUrl) {
        addContent(Content.builder()
                .text(Content.Type.IMAGE_URL.getName())
                .imageUrl(ImageUrl.builder().url(imageUrl).build())
                .build());
    }

    /**
     * 添加对话内容
     */
    public void addContent(Content content) {
        this.content.add(content);
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/BaseChatCompletionRequest.java
================================================
package com.ai.openai.endPoint.chat.req;

import com.ai.openai.endPoint.chat.ResponseFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
import lombok.experimental.SuperBuilder;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class BaseChatCompletionRequest implements Serializable {

    /**
     * 要使用的模型的 ID
     */
    @Builder.Default
    private String model = Model.GPT_3_5_TURBO.getModuleName();

    /**
     * 介于 -2.0 和 2.0 之间的数字,默认值为 0
     * 正值会根据新标记在文本中的现有频率来惩罚新标记从而降低模型逐字重复同一行的可能性
     */
    @JsonProperty("frequency_penalty")
    private Double frequencyPenalty;

    /**
     * 修改指定标记出现的可能性,默认值为 null
     */
    @JsonProperty("logit_bias")
    private Map logitBias;

    /**
     * 输出字符串限制;0 ~ 4096
     */
    @JsonProperty("max_tokens")
    private Integer maxTokens;

    /**
     * 为每个提示生成的完成次数,默认值为 1
     */
    private Integer n;

    /**
     * 介于 -2.0 和 2.0 之间的数字,默认值为 0
     * 正值会根据新标记到目前为止是否出现在文本中来惩罚它们从而增加模型谈论新主题的可能性
     */
    @JsonProperty("presence_penalty")
    private Double presencePenalty;

    /**
     * 指定模型必须输出的格式的对象。
     */
    @JsonProperty("response_format")
    private ResponseFormat responseFormat;

    private Integer seed;

    /**
     * 停止输出标识,默认值为 null
     * 最多 4 个序列,API 将停止生成更多令牌
     */
    private List<String> stop;

    /**
     * 使用什么采样温度,介于 0 和 2 之间,默认值为 1
     * 较高的值(如 0.8)将使输出更加随机,而较低的值(如 0.2)将使其更具集中性和确定性
     */
    private Double temperature;

    /**
     * 默认值为 1
     * 温度采样的替代方法,称为核采样,其中模型考虑具有top_p概率质量的标记的结果。因此,0.1 表示仅考虑包含前 10% 概率质量的代币。
     */
    @JsonProperty("top_p")
    private Double topP;

    /**
     * 调用标识,避免重复调用
     */
    private String user;

    @Getter
    @AllArgsConstructor
    public enum Model {
        GPT_3_5_TURBO("gpt-3.5-turbo"), GPT_4("gpt-4"), GPT_4_32K("gpt-4-32k"),
        GPT_4_VISION_PREVIEW("gpt-4-vision-preview"),
        ;
        private String moduleName;
    }
}



================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/DefaultChatCompletionRequest.java
================================================
package com.ai.openai.endPoint.chat.req;

import com.ai.core.exception.Constants;
import com.ai.openai.endPoint.chat.msg.DefaultMessage;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.experimental.SuperBuilder;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @Description: 默认对话方式
 **/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DefaultChatCompletionRequest extends BaseChatCompletionRequest implements Serializable {

    /**
     * 构成对话的消息列表
     */
    @NonNull
    private List<DefaultMessage> messages;

    /**
     * 是否为流式输出,默认值为 false
     */
    private Boolean stream;

    /**
     * 构造基础的 DefaultChatCompletionRequest
     *
     * @param question 问题内容
     */
    public static DefaultChatCompletionRequest baseBuild(String question) {
        return DefaultChatCompletionRequest
                .builder()
                .messages(new ArrayList<>(Collections.singletonList(DefaultMessage.builder().role(Constants.Role.USER.getRoleName()).content(question).build())))
                .build();
    }

    /**
     * 上下文对话时,添加问答内容
     *
     * @param message 问答内容
     */
    public void addMessage(DefaultMessage message) {
        this.messages.add(message);
    }

    /**
     * 上下文对话时,添加问答内容
     *
     * @param role    角色
     * @param content 内容
     */
    public void addMessage(String role, String content) {
        this.addMessage(DefaultMessage.builder().role(role).content(content).build());
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/FuncChatCompletionRequest.java
================================================
package com.ai.openai.endPoint.chat.req;

import com.ai.core.exception.Constants;
import com.ai.openai.endPoint.chat.msg.DefaultMessage;
import com.ai.openai.endPoint.chat.tools.Tool;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.experimental.SuperBuilder;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @Description: 函数式对话
 **/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class FuncChatCompletionRequest extends BaseChatCompletionRequest implements Serializable {

    /**
     * 构成对话的消息列表
     */
    @NonNull
    private List<DefaultMessage> messages;

    /**
     * 模型可能调用的工具列表。当前版本仅支持:functions
     */
    private List<Tool> tools;

    /**
     * 控制模型调用哪个(如果有)函数。
     */
    @JsonProperty("tool_choice")
    private Object toolChoice;

    /**
     * 构造基础的 DefaultChatCompletionRequest
     *
     * @param question 问题内容
     */
    public static FuncChatCompletionRequest baseBuild(String question) {
        return FuncChatCompletionRequest.builder()
                .messages(new ArrayList<>(Collections.singletonList(DefaultMessage.builder().role(Constants.Role.USER.getRoleName()).content(question).build())))
                .build();
    }

    /**
     * 上下文对话时,添加问答内容
     *
     * @param message 问答内容
     */
    public void addMessage(DefaultMessage message) {
        this.messages.add(message);
    }

    /**
     * 上下文对话时,添加问答内容
     *
     * @param role    角色
     * @param content 内容
     */
    public void addMessage(String role, String content) {
        this.addMessage(DefaultMessage.builder().role(role).content(content).build());
    }


}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/ImgChatCompletionRequest.java
================================================
package com.ai.openai.endPoint.chat.req;

import com.ai.openai.endPoint.chat.msg.ImgMessage;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.experimental.SuperBuilder;

import java.io.Serializable;
import java.util.List;

/**
 * @Description: 输入图片对话
 **/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ImgChatCompletionRequest extends BaseChatCompletionRequest implements Serializable {

    /**
     * 构成对话的消息列表
     */
    @NonNull
    private List<ImgMessage> messages;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/QaCompletionRequest.java
================================================
package com.ai.openai.endPoint.chat.req;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class QaCompletionRequest implements Serializable {

    /**
     * 要使用的模型的 ID
     */
    @Builder.Default
    private String model = Model.GPT_3_5_TURBO.getModelName();

    /**
     * 问题描述
     */
    @NonNull
    private String prompt;

    /**
     * 默认值为 1
     * 在服务器端生成回答并返回“最佳”(每个令牌的对数概率最高的一个)。无法流式传输结果。
     */
    @JsonProperty("best_of")
    private Integer bestOf;

    /**
     * 介于 -2.0 和 2.0 之间的数字,默认值为 0
     * 正值会根据新标记在文本中的现有频率来惩罚新标记从而降低模型逐字重复同一行的可能性
     */
    @JsonProperty("frequency_penalty")
    private Double frequencyPenalty;

    /**
     * 修改指定标记出现的可能性,默认值为 null
     */
    @JsonProperty("logit_bias")
    private Map logitBias;

    /**
     * 默认值为 null
     * 包括最有可能的令牌以及所选令牌的对数概率。
     */
    private Integer logprobs;

    /**
     * 输出字符串限制;0 ~ 4096
     */
    @JsonProperty("max_tokens")
    private Integer maxTokens;

    /**
     * 为每个提示生成的完成次数,默认值为 1
     */
    private Integer n;

    /**
     * 介于 -2.0 和 2.0 之间的数字,默认值为 0
     * 正值会根据新标记到目前为止是否出现在文本中来惩罚它们从而增加模型谈论新主题的可能性
     */
    @JsonProperty("presence_penalty")
    private Double presencePenalty;

    /**
     * 停止输出标识,默认值为 null
     * 最多 4 个序列,API 将停止生成更多令牌
     */
    private List<String> stop;

    /**
     * 是否为流式输出,默认值为 false
     */
    private Boolean stream;

    /**
     * 使用什么采样温度,介于 0 和 2 之间,默认值为 1
     * 较高的值(如 0.8)将使输出更加随机,而较低的值(如 0.2)将使其更具集中性和确定性
     */
    private Double temperature;

    /**
     * 默认值为 1
     * 温度采样的替代方法,称为核采样,其中模型考虑具有top_p概率质量的标记的结果。因此,0.1 表示仅考虑包含前 10% 概率质量的代币。
     */
    @JsonProperty("top_p")
    private Double topP = 1d;

    /**
     * 调用标识,避免重复调用
     */
    private String user;

    /**
     * 构造基础请求内容
     *
     * @param question 问题内容
     * @return 简单问答请求体
     */
    public static QaCompletionRequest baseBuild(String question) {
        return QaCompletionRequest.builder().prompt(question).build();
    }

    @Getter
    @AllArgsConstructor
    public enum Model {
        GPT_3_5_TURBO("gpt-3.5-turbo-instruct"), GPT_4("gpt-4"), GPT_4_32K("gpt-4-32k"),
        ;
        private String modelName;
    }
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/resp/ChatCompletionResponse.java
================================================
package com.ai.openai.endPoint.chat.resp;

import com.ai.openai.common.Usage;
import com.ai.openai.endPoint.chat.ChatChoice;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
 * @description 聊天请求结果信息
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ChatCompletionResponse implements Serializable {

    /**
     * 完成的唯一标识符
     */
    private String id;

    /**
     * 对话信息
     */
    private List<ChatChoice> choices;

    /**
     * 对象
     */
    private String object;

    /**
     * 创建完成时的 Unix 时间戳(以秒为单位)。
     */
    private Long created;

    /**
     * 用于完成的模型
     */
    private String model;

    @JsonProperty("system_fingerprint")
    private String systemFingerprint;

    /**
     * 结束原因
     */
    @JsonProperty("finish_reason")
    private String finishReason;

    /**
     * 完成请求的使用情况统计信息
     */
    private Usage usage;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/resp/QaCompletionResponse.java
================================================
package com.ai.openai.endPoint.chat.resp;


import com.ai.openai.common.Usage;
import com.ai.openai.endPoint.chat.QaChoice;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
 * @Description: 简单问答返回信息
 **/
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class QaCompletionResponse implements Serializable {

    /**
     * 完成的唯一标识符
     */
    private String id;

    /**
     * 模型为输入提示生成的完成选项列表
     */
    private List<QaChoice> choices;

    /**
     * 创建完成时的 Unix 时间戳(以秒为单位)。
     */
    private Long created;

    /**
     * 用于完成的模型
     */
    private String model;

    /**
     * 对象类型,始终为“text_completion”
     */
    private String object;

    /**
     * 完成请求的使用情况统计信息
     */
    private Usage usage;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/tools/Tool.java
================================================
package com.ai.openai.endPoint.chat.tools;

import lombok.*;

import java.io.Serializable;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Tool implements Serializable {

    /**
     * 目前只支持:function
     *
     * @see Type
     */
    private String type;

    private ToolFunction function;

    @Getter
    @AllArgsConstructor
    public enum Type {
        FUNCTION("function"),
        ;
        private final String name;
    }
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/tools/ToolCall.java
================================================
package com.ai.openai.endPoint.chat.tools;

import lombok.*;

import java.io.Serializable;

/**
 * @Description: 函数式对话返回的函数信息
 **/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ToolCall implements Serializable {

    private String id;

    private String type;

    private ToolCallFunction function;

    @Getter
    @AllArgsConstructor
    public enum Type {
        FUNCTION("function"),
        ;
        private final String name;
    }
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/tools/ToolCallFunction.java
================================================
package com.ai.openai.endPoint.chat.tools;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @Description: TODO
 **/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ToolCallFunction implements Serializable {
    /**
     * 方法名
     */
    private String name;
    /**
     * 方法参数
     */
    private String arguments;
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/tools/ToolFunction.java
================================================
package com.ai.openai.endPoint.chat.tools;

import com.ai.openai.endPoint.chat.Parameters;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ToolFunction implements Serializable {

    /**
     * 要调用的函数的名称。必须是 a-z、A-Z、0-9 或包含下划线和短划线,最大长度为 64。
     */
    private String name;

    /**
     * 对函数所执行操作的描述,模型使用它来选择何时以及如何调用该函数。
     */
    private String description;

    /**
     * 函数接受的参数,描述为 JSON 架构对象。
     */
    private Parameters parameters;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/embeddings/EmbeddingObject.java
================================================
package com.ai.openai.endPoint.embeddings;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;


@Data
@AllArgsConstructor
@NoArgsConstructor
public class EmbeddingObject implements Serializable {

    /**
     * 嵌入的内容
     */
    @JsonIgnore
    private String content;

    /**
     * 嵌入列表中嵌入的索引
     */
    private Integer index;

    /**
     * 嵌入向量,它是浮点数的列表
     */
    private double[] embedding;

    /**
     * 对象类型,始终为“embedding”。
     */
    private String object;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/embeddings/req/EmbeddingCompletionRequest.java
================================================
package com.ai.openai.endPoint.embeddings.req;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class EmbeddingCompletionRequest implements Serializable {

    /**
     * 输入要嵌入的文本,编码为字符串或标记数组。
     * 若要在单个请求中嵌入多个输入,请传递字符串数组或令牌数组。
     */
    @NonNull
    private List<String> input;

    /**
     * 要使用的模型的 ID。
     */
    @Builder.Default
    private String model = Model.TEXT_EMBEDDING_ADA_002.getModelName();

    /**
     * 要返回嵌入的格式。
     */
    @JsonProperty("encoding_format")
    private String encodingFormat;

    /**
     * 代表最终用户的唯一标识符
     */
    private String user;

    /**
     * 构造基础请求参数
     *
     * @param input 文本
     * @return 请求参数
     */
    public static EmbeddingCompletionRequest baseBuild(String input) {
        return baseBuild(Arrays.asList(input));
    }

    /**
     * 构造基础请求参数
     *
     * @param inputList 文本数组
     * @return 请求参数
     */
    public static EmbeddingCompletionRequest baseBuild(List<String> inputList) {
        return EmbeddingCompletionRequest.builder().input(inputList).build();
    }

    @Getter
    @AllArgsConstructor
    public enum Model {
        TEXT_EMBEDDING_ADA_002("text-embedding-ada-002"),
        ;
        private final String modelName;
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/embeddings/resp/EmbeddingCompletionResponse.java
================================================
package com.ai.openai.endPoint.embeddings.resp;

import com.ai.openai.common.Usage;
import com.ai.openai.endPoint.embeddings.EmbeddingObject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class EmbeddingCompletionResponse implements Serializable {

    /**
     * 参考示例返回:
     * {
     * "object": "list",
     * "data": [
     * {
     * "object": "embedding",
     * "embedding": [
     * 0.0023064255,
     * -0.009327292,
     * .... (1536 floats total for ada-002)
     * -0.0028842222,
     * ],
     * "index": 0
     * }
     * ],
     * "model": "text-embedding-ada-002",
     * "usage": {
     * "prompt_tokens": 8,
     * "total_tokens": 8
     * }
     * }
     */
    private String object;

    /**
     * 结果数组
     */
    private List<EmbeddingObject> data;

    private String model;

    private Usage usage;


}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/files/FileObject.java
================================================
package com.ai.openai.endPoint.files;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class FileObject implements Serializable {

    /**
     * 文件标识符,可在 API 端点中引用
     */
    private String id;

    /**
     * 文件大小(以字节为单位)
     */
    private Long bytes;

    /**
     * 创建文件时的 Unix 时间戳(以秒为单位)
     */
    @JsonProperty("created_at")
    private Long createdAt;

    /**
     * 文件的名称
     */
    private String filename;

    /**
     * 对象类型,始终为:file
     */
    private String object;

    /**
     * 文件的预期用途
     */
    private String purpose;

    /**
     * 荒废的。文件的当前状态
     */
    @Deprecated
    private String status;

    /**
     * 荒废的。有关微调训练文件验证失败的原因的详细信息
     */
    @Deprecated
    @JsonProperty("status_details")
    private String statusDetails;
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/files/resp/DeleteFileResponse.java
================================================
package com.ai.openai.endPoint.files.resp;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;


@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DeleteFileResponse implements Serializable {

    /**
     * 文件ID
     */
    private String id;
    private String object;
    private Boolean deleted;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/FineTuneError.java
================================================
package com.ai.openai.endPoint.fineTuning;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class FineTuneError implements Serializable {

    /**
     * 错误信息
     */
    private String message;

    /**
     * 错误类型
     */
    private String type;

    /**
     * 错误参数
     */
    private String param;

    /**
     * 错误码
     */
    private String code;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/FineTuningEvent.java
================================================
package com.ai.openai.endPoint.fineTuning;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class FineTuningEvent implements Serializable {

    private String object;

    private String id;

    /**
     * 创建微调作业时的 Unix 时间戳
     */
    @JsonProperty("created_at")
    private Long createdAt;

    private String level;

    private String message;

    private String type;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/HyperParameters.java
================================================
package com.ai.openai.endPoint.fineTuning;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;

@Getter
@Slf4j
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
@AllArgsConstructor
public class HyperParameters implements Serializable {

    /**
     * 每批样本数。较大的批量大小意味着模型参数 更新频率较低,但方差较低。
     */
    @JsonProperty("batch_size")
    private String batchSize;

    /**
     * 学习率的比例因子。较小的学习率可能有助于避免 过拟合。
     */
    @JsonProperty("learning_rate_multiplier")
    private String learningRateMultiplier;

    /**
     * 要训练模型的纪元数。一个纪元是指一个完整的周期 通过训练数据集。
     */
    @JsonProperty("n_epochs")
    private String nEpochs;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/req/FineTuningRequest.java
================================================
package com.ai.openai.endPoint.fineTuning.req;

import com.ai.openai.endPoint.fineTuning.HyperParameters;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import java.io.Serializable;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class FineTuningRequest implements Serializable {

    /**
     * 微调的模型的名称
     */
    @Builder.Default
    private String model = Model.GPT_3_5_TURBO_1106.getModelName();

    /**
     * 包含训练数据的已上传文件的 ID
     */
    @NonNull
    @JsonProperty("training_file")
    private String trainingFile;

    /**
     * 用于微调作业的超参数
     */
    @JsonProperty("hyperparameters")
    private HyperParameters hyperParameters;

    /**
     * 最多 18 个字符的字符串,将添加到微调的模型名称中。
     */
    private String suffix;

    /**
     * 包含验证数据的上载文件的 ID
     */
    @JsonProperty("validation_file")
    private String validationFile;

    @Getter
    @AllArgsConstructor
    public enum Model {
        GPT_3_5_TURBO_1106("gpt-3.5-turbo-1106"), GPT_3_5_TURBO_0613("gpt-3.5-turbo-0613"), BABBAGE_002("babbage-002"), GPT_4_0613("gpt-4-0613"), DAVINCI_002("davinci-002"),
        ;
        private final String modelName;
    }
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/req/ListFineTuningRequest.java
================================================
package com.ai.openai.endPoint.fineTuning.req;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ListFineTuningRequest implements Serializable {

    /**
     * 上一个分页请求中最后一个作业的标识符
     */
    private String after;

    /**
     * 要检索的微调作业数
     */
    private Integer limit;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/resp/FineTuningResponse.java
================================================
package com.ai.openai.endPoint.fineTuning.resp;

import com.ai.openai.endPoint.fineTuning.HyperParameters;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class FineTuningResponse implements Serializable {

    /**
     * 对象标识符,可在 API 端点中引用
     */
    private String id;

    /**
     * 创建微调作业时的 Unix 时间戳
     */
    @JsonProperty("created_at")
    private Long createdAt;

    /**
     * 对于具有的微调作业,这将包含有关失败原因的详细信息
     */
//    private FineTuneError error;

    /**
     * 正在创建的微调模型的名称。如果微调作业仍在运行,则该值将为 null
     */
    @JsonProperty("fine_tuned_model")
    private String fineTunedModel;

    /**
     * 微调作业完成时的 Unix 时间戳(以秒为单位)。如果微调作业仍在运行,则该值将为 null
     */
    @JsonProperty("finished_at")
    private Long finishedAt;

    /**
     * 用于微调作业的超参数
     */
    @JsonProperty("hyperparameters")
    private HyperParameters hyperparameters;

    /**
     * 正在微调的基本模型
     */
    private String model;

    /**
     * 对象类型,始终为“fine_tuning.job”
     */
    private String object;

    /**
     * 拥有微调作业的组织
     */
    @JsonProperty("organization_id")
    private String organizationId;

    /**
     * 微调作业的编译结果文件 ID
     */
    @JsonProperty("result_files")
    private List<String> resultFiles;

    /**
     * 微调作业的当前状态
     */
    private String status;

    /**
     * 此微调作业处理的计费令牌总数
     */
    @JsonProperty("trained_tokens")
    private Integer trainedTokens;

    /**
     * 用于训练的文件 ID
     */
    @JsonProperty("training_file")
    private String trainingFile;

    /**
     * 用于验证的文件 ID
     */
    @JsonProperty("validation_file")
    private String validationFile;

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/images/ImageObject.java
================================================
package com.ai.openai.endPoint.images;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ImageObject {

    private String url;
    @JsonProperty("b64_json")
    private String b64Json;
    @JsonProperty("revised_prompt")
    private String revisedPrompt;


}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/images/req/CreateImageRequest.java
================================================
package com.ai.openai.endPoint.images.req;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import java.io.Serializable;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CreateImageRequest implements Serializable {

    /**
     * 所需图像的文本描述。的最大长度为 1000 个字符,4000 个字符。
     */
    private String prompt;

    /**
     * 用于图像生成的模型
     * <p>
     * 默认为 dall-e-2
     *
     * @see Model
     */
    @Builder.Default
    private String model = Model.DALL_E_2.getName();

    /**
     * 要生成的图像数。必须介于 1 和 10 之间,dall-e-3只能为1。
     */
    @Builder.Default
    private Integer n = 1;

    /**
     * 将生成的图像的质量。 创建具有更精细细节和更高一致性的图像。
     *
     * @see Quality
     */
    private String quality;

    /**
     * 返回生成的图像的格式:url、b64_json
     */
    @JsonProperty("response_format")
    private String responseFormat;

    /**
     * 图片尺寸,默认值:1024x1024
     * dall-e-2支持:256x256, 512x512, or 1024x1024
     * dall-e-3支持:1024x1024, 1792x1024, or 1024x1792
     */
    private String size;

    /**
     * 生成的图像的样式。
     * 此参数仅仅dall-e-3,取值范围:vivid、natural
     * 默认值:vivid
     *
     * @see Style
     */
    private String style;

    /**
     * 代表最终用户的唯一标识符
     */
    private String user;

    /**
     * 构建基础请求内容
     *
     * @param prompt 提示词
     * @return 请求参数
     */
    public static CreateImageRequest baseBuild(String prompt) {
        return CreateImageRequest.builder().prompt(prompt).build();
    }

    /**
     * 图片生成模型
     */
    @Getter
    @AllArgsConstructor
    public enum Model {
        DALL_E_2("dall-e-2"),
        DALL_E_3("dall-e-3"),
        ;
        private final String name;
    }

    /**
     * 生成图片质量
     */
    @Getter
    @AllArgsConstructor
    public enum Quality {
        STANDARD("standard"),
        HD("hd"),
        ;
        private final String quality;
    }

    /**
     * 生成图片风格
     */
    @Getter
    @AllArgsConstructor
    public enum Style {
        VIVID("vivid"),
        NATURAL("natural"),
        ;
        private final String style;
    }

    @Getter
    @AllArgsConstructor
    public enum Format {
        URL("url"),
        B64JSON("b64_json"),
        ;
        private final String format;
    }


}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/images/req/ImageEditRequest.java
================================================
package com.ai.openai.endPoint.images.req;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import java.io.Serializable;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ImageEditRequest {

    /**
     * 必选项:描述文字,最多1000字符
     */
    @NonNull
    private String prompt;

    /**
     * 为每个提示生成的完成次数。
     */
    @Builder.Default
    private Integer n = 1;

    /**
     * 256x256
     * 512x512
     * 1024x1024
     */
    @Builder.Default
    private String size = SizeEnum.size_1024.getName();

    @JsonProperty("response_format")
    @Builder.Default
    private String responseFormat = ResponseFormat.URL.getName();

    private String user;

    /**
     * 构造基础请求参数
     *
     * @param prompt 提示词
     * @return 请求参数
     */
    public static ImageEditRequest baseBuild(String prompt) {
        return ImageEditRequest.builder().prompt(prompt).build();
    }

    @Getter
    @AllArgsConstructor
    public enum SizeEnum implements Serializable {
        size_1024_1792("1024x1792"),
        size_1792_1024("1792x1024"),
        size_1024("1024x1024"),
        size_512("512x512"),
        size_256("256x256"),
        ;
        private final String name;

    }

    @AllArgsConstructor
    @Getter
    public enum ResponseFormat implements Serializable {
        URL("url"),
        B64_JSON("b64_json"),
        ;

        private final String name;
    }

}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/images/req/ImageVariationRequest.java
================================================
package com.ai.openai.endPoint.images.req;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;

@Slf4j
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ImageVariationRequest {

    /**
     * 为每个提示生成的完成次数。
     */
    @Builder.Default
    private Integer n = 1;
    /**
     * 256x256
     * 512x512
     * 1024x1024
     */
    @Builder.Default
    private String size = SizeEnum.size_1024.getName();

    @JsonProperty("response_format")
    @Builder.Default
    private String responseFormat = ResponseFormat.URL.getName();

    private String user;

    @Getter
    @AllArgsConstructor
    public enum SizeEnum implements Serializable {
        size_1024_1792("1024x1792"),
        size_1792_1024("1792x1024"),
        size_1024("1024x1024"),
        size_512("512x512"),
        size_256("256x256"),
        ;
        private final String name;

    }

    @AllArgsConstructor
    @Getter
    public enum ResponseFormat implements Serializable {
        URL("url"),
        B64_JSON("b64_json"),
        ;

        private final String name;
    }


}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/images/resp/CreateImageResponse.java
================================================
package com.ai.openai.endPoint.images.resp;

import com.ai.openai.endPoint.images.ImageObject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CreateImageResponse {
    private Long created;
    private List<ImageObject> data;
}


================================================
FILE: ai-openai/src/main/java/com/ai/openai/endPoint/models/ModelObject.java
================================================
package com.ai.openai.endPoint.models;


import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ModelObject {

    /**
     * 模型标识符,可在 API 端点中引用。
     */
    private String id;

    /**
     * 对象类型,始终为“model”。
     */
    private String object;

    /**
     * 创建模型时的 Unix 时间戳(以秒为单位)。
     */
    private long created;

    /**
     * 拥有模型的组织。
     */
    @JsonProperty("owned_by")
    private String ownedBy;

}


================================================
FILE: ai-openai/src/
Download .txt
gitextract_iuc1x97d/

├── README.md
├── ai-baidu/
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   └── java/
│       │       └── com/
│       │           └── ai/
│       │               └── baidu/
│       │                   ├── achieve/
│       │                   │   ├── ApiData.java
│       │                   │   ├── Configuration.java
│       │                   │   ├── defaults/
│       │                   │   │   ├── DefaultBaiduSessionFactory.java
│       │                   │   │   └── session/
│       │                   │   │       ├── DefaultAggregationSession.java
│       │                   │   │       ├── DefaultChatSession.java
│       │                   │   │       ├── DefaultEmbeddingSession.java
│       │                   │   │       ├── DefaultImageSession.java
│       │                   │   │       └── Session.java
│       │                   │   └── standard/
│       │                   │       ├── api/
│       │                   │       │   └── BaiduApiServer.java
│       │                   │       └── session/
│       │                   │           ├── AggregationSession.java
│       │                   │           ├── ChatSession.java
│       │                   │           ├── EmbeddingSession.java
│       │                   │           └── ImageSession.java
│       │                   ├── common/
│       │                   │   ├── ApiUrl.java
│       │                   │   └── Usage.java
│       │                   ├── endPoint/
│       │                   │   ├── auth/
│       │                   │   │   └── resp/
│       │                   │   │       └── AuthResponse.java
│       │                   │   ├── chat/
│       │                   │   │   ├── Message.java
│       │                   │   │   ├── SearchResult.java
│       │                   │   │   ├── req/
│       │                   │   │   │   └── ChatRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── ChatResponse.java
│       │                   │   ├── embedding/
│       │                   │   │   ├── EmbeddingData.java
│       │                   │   │   ├── req/
│       │                   │   │   │   └── EmbeddingRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── EmbeddingResponse.java
│       │                   │   └── images/
│       │                   │       ├── ImageData.java
│       │                   │       ├── req/
│       │                   │       │   └── ImageRequest.java
│       │                   │       └── resp/
│       │                   │           └── ImageResponse.java
│       │                   └── interceptor/
│       │                       └── ResponseInterceptor.java
│       └── test/
│           └── java/
│               └── com/
│                   └── ai/
│                       └── baidu/
│                           ├── ChatApiTest.java
│                           ├── EmbeddingApiTest.java
│                           └── ImageApiTest.java
├── ai-common/
│   ├── pom.xml
│   └── src/
│       └── main/
│           └── java/
│               └── com/
│                   └── ai/
│                       └── common/
│                           └── utils/
│                               ├── Exceptions.java
│                               ├── ImageUtils.java
│                               ├── JsonUtils.java
│                               └── ValidationUtils.java
├── ai-core/
│   ├── pom.xml
│   └── src/
│       └── main/
│           └── java/
│               └── com/
│                   └── ai/
│                       └── core/
│                           ├── config/
│                           │   └── BaseConfiguration.java
│                           ├── exception/
│                           │   ├── BaseException.java
│                           │   ├── Constants.java
│                           │   └── IError.java
│                           ├── factory/
│                           │   └── SessionFactory.java
│                           └── strategy/
│                               ├── KeyStrategy.java
│                               └── impl/
│                                   ├── FirstKeyStrategy.java
│                                   └── RandomKeyStrategy.java
├── ai-openai/
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   └── java/
│       │       └── com/
│       │           └── ai/
│       │               └── openai/
│       │                   ├── Product.java
│       │                   ├── Singleton.java
│       │                   ├── ThreadPrint.java
│       │                   ├── achieve/
│       │                   │   ├── Configuration.java
│       │                   │   ├── defaults/
│       │                   │   │   ├── DefaultOpenAiSessionFactory.java
│       │                   │   │   └── session/
│       │                   │   │       ├── DefaultAggregationSession.java
│       │                   │   │       ├── DefaultAudioSession.java
│       │                   │   │       ├── DefaultChatSession.java
│       │                   │   │       ├── DefaultEmbeddingSession.java
│       │                   │   │       ├── DefaultFilesSession.java
│       │                   │   │       ├── DefaultFineTuningSession.java
│       │                   │   │       ├── DefaultImageSession.java
│       │                   │   │       ├── DefaultModelSession.java
│       │                   │   │       ├── DefaultModerationSession.java
│       │                   │   │       └── Session.java
│       │                   │   └── standard/
│       │                   │       ├── api/
│       │                   │       │   └── OpenaiApiServer.java
│       │                   │       └── session/
│       │                   │           ├── AggregationSession.java
│       │                   │           ├── AudioSession.java
│       │                   │           ├── ChatSession.java
│       │                   │           ├── EmbeddingSession.java
│       │                   │           ├── FilesSession.java
│       │                   │           ├── FineTuningSession.java
│       │                   │           ├── ImageSession.java
│       │                   │           ├── ModelSession.java
│       │                   │           └── ModerationSession.java
│       │                   ├── common/
│       │                   │   ├── ApiUrl.java
│       │                   │   ├── CommonListResponse.java
│       │                   │   └── Usage.java
│       │                   ├── endPoint/
│       │                   │   ├── audio/
│       │                   │   │   ├── req/
│       │                   │   │   │   ├── SttCompletionRequest.java
│       │                   │   │   │   └── TtsCompletionRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── SttCompletionResponse.java
│       │                   │   ├── chat/
│       │                   │   │   ├── ChatChoice.java
│       │                   │   │   ├── Parameters.java
│       │                   │   │   ├── QaChoice.java
│       │                   │   │   ├── ResponseFormat.java
│       │                   │   │   ├── msg/
│       │                   │   │   │   ├── BaseMessage.java
│       │                   │   │   │   ├── Content.java
│       │                   │   │   │   ├── DefaultMessage.java
│       │                   │   │   │   ├── ImageUrl.java
│       │                   │   │   │   └── ImgMessage.java
│       │                   │   │   ├── req/
│       │                   │   │   │   ├── BaseChatCompletionRequest.java
│       │                   │   │   │   ├── DefaultChatCompletionRequest.java
│       │                   │   │   │   ├── FuncChatCompletionRequest.java
│       │                   │   │   │   ├── ImgChatCompletionRequest.java
│       │                   │   │   │   └── QaCompletionRequest.java
│       │                   │   │   ├── resp/
│       │                   │   │   │   ├── ChatCompletionResponse.java
│       │                   │   │   │   └── QaCompletionResponse.java
│       │                   │   │   └── tools/
│       │                   │   │       ├── Tool.java
│       │                   │   │       ├── ToolCall.java
│       │                   │   │       ├── ToolCallFunction.java
│       │                   │   │       └── ToolFunction.java
│       │                   │   ├── embeddings/
│       │                   │   │   ├── EmbeddingObject.java
│       │                   │   │   ├── req/
│       │                   │   │   │   └── EmbeddingCompletionRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── EmbeddingCompletionResponse.java
│       │                   │   ├── files/
│       │                   │   │   ├── FileObject.java
│       │                   │   │   └── resp/
│       │                   │   │       └── DeleteFileResponse.java
│       │                   │   ├── fineTuning/
│       │                   │   │   ├── FineTuneError.java
│       │                   │   │   ├── FineTuningEvent.java
│       │                   │   │   ├── HyperParameters.java
│       │                   │   │   ├── req/
│       │                   │   │   │   ├── FineTuningRequest.java
│       │                   │   │   │   └── ListFineTuningRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── FineTuningResponse.java
│       │                   │   ├── images/
│       │                   │   │   ├── ImageObject.java
│       │                   │   │   ├── req/
│       │                   │   │   │   ├── CreateImageRequest.java
│       │                   │   │   │   ├── ImageEditRequest.java
│       │                   │   │   │   └── ImageVariationRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── CreateImageResponse.java
│       │                   │   ├── models/
│       │                   │   │   ├── ModelObject.java
│       │                   │   │   └── resp/
│       │                   │   │       └── DeleteFineTuneModelResponse.java
│       │                   │   └── moderations/
│       │                   │       ├── Categories.java
│       │                   │       ├── CategoryScores.java
│       │                   │       ├── Result.java
│       │                   │       ├── req/
│       │                   │       │   └── ModerationRequest.java
│       │                   │       └── resp/
│       │                   │           └── ModerationResponse.java
│       │                   └── interceptor/
│       │                       ├── HeaderInterceptor.java
│       │                       └── ResponseInterceptor.java
│       └── test/
│           └── java/
│               └── com/
│                   └── ai/
│                       └── openai/
│                           ├── AudioApiTest.java
│                           ├── ChatApiTest.java
│                           ├── EmbeddingApiTest.java
│                           ├── FilesApiTest.java
│                           ├── FineTuningApiTest.java
│                           ├── ImageApiTest.java
│                           ├── ModelApiTest.java
│                           └── ModerationApiTest.java
├── ai-spark/
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   └── java/
│       │       └── com/
│       │           └── ai/
│       │               └── spark/
│       │                   ├── achieve/
│       │                   │   ├── ApiData.java
│       │                   │   ├── Configuration.java
│       │                   │   ├── defaults/
│       │                   │   │   ├── DefaultSparkSessionFactory.java
│       │                   │   │   ├── listener/
│       │                   │   │   │   ├── BaseListener.java
│       │                   │   │   │   ├── ChatListener.java
│       │                   │   │   │   ├── DocumentChatListener.java
│       │                   │   │   │   └── ImageUnderstandingListener.java
│       │                   │   │   └── session/
│       │                   │   │       ├── DefaultAggregationSession.java
│       │                   │   │       ├── DefaultAudioSession.java
│       │                   │   │       ├── DefaultChatSession.java
│       │                   │   │       ├── DefaultDocumentSession.java
│       │                   │   │       ├── DefaultEmbeddingSession.java
│       │                   │   │       ├── DefaultImageSession.java
│       │                   │   │       └── Session.java
│       │                   │   └── standard/
│       │                   │       ├── api/
│       │                   │       │   └── SparkApiServer.java
│       │                   │       └── session/
│       │                   │           ├── AggregationSession.java
│       │                   │           ├── AudioSession.java
│       │                   │           ├── ChatSession.java
│       │                   │           ├── DocumentSession.java
│       │                   │           ├── EmbeddingSession.java
│       │                   │           └── ImageSession.java
│       │                   ├── common/
│       │                   │   ├── Constants.java
│       │                   │   ├── SparkApiUrl.java
│       │                   │   ├── Usage.java
│       │                   │   ├── UsageText.java
│       │                   │   └── utils/
│       │                   │       └── AuthUtils.java
│       │                   ├── endPoint/
│       │                   │   ├── audio/
│       │                   │   │   ├── Audio.java
│       │                   │   │   ├── AudioHeader.java
│       │                   │   │   ├── AudioParameter.java
│       │                   │   │   ├── AudioPayload.java
│       │                   │   │   ├── AudioText.java
│       │                   │   │   ├── Oral.java
│       │                   │   │   ├── Pybuf.java
│       │                   │   │   ├── Tts.java
│       │                   │   │   ├── req/
│       │                   │   │   │   └── AudioRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── AudioResponse.java
│       │                   │   ├── chat/
│       │                   │   │   ├── Chat.java
│       │                   │   │   ├── ChatHeader.java
│       │                   │   │   ├── ChatParameter.java
│       │                   │   │   ├── ChatPayload.java
│       │                   │   │   ├── ChatText.java
│       │                   │   │   ├── Choice.java
│       │                   │   │   ├── Message.java
│       │                   │   │   ├── document/
│       │                   │   │   │   └── ChatExtends.java
│       │                   │   │   ├── function/
│       │                   │   │   │   ├── Function.java
│       │                   │   │   │   ├── FunctionParameter.java
│       │                   │   │   │   └── FunctionText.java
│       │                   │   │   ├── req/
│       │                   │   │   │   ├── ChatRequest.java
│       │                   │   │   │   └── DocumentChatRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       ├── ChatResponse.java
│       │                   │   │       └── DocumentChatResponse.java
│       │                   │   ├── document/
│       │                   │   │   ├── Data.java
│       │                   │   │   ├── req/
│       │                   │   │   │   └── FileUploadRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       ├── DocumentSummaryResponse.java
│       │                   │   │       └── FileUploadResponse.java
│       │                   │   ├── embedding/
│       │                   │   │   ├── Emb.java
│       │                   │   │   ├── EmbeddingHeader.java
│       │                   │   │   ├── EmbeddingMessage.java
│       │                   │   │   ├── EmbeddingParameter.java
│       │                   │   │   ├── EmbeddingPayload.java
│       │                   │   │   ├── Feature.java
│       │                   │   │   ├── req/
│       │                   │   │   │   └── EmbeddingRequest.java
│       │                   │   │   └── resp/
│       │                   │   │       └── EmbeddingResponse.java
│       │                   │   └── images/
│       │                   │       ├── ImageChat.java
│       │                   │       ├── ImageHeader.java
│       │                   │       ├── ImageParameter.java
│       │                   │       ├── ImagePayload.java
│       │                   │       ├── ImageUnderstandingChat.java
│       │                   │       ├── ImageUnderstandingParameter.java
│       │                   │       ├── ImageUnderstandingPayload.java
│       │                   │       ├── req/
│       │                   │       │   ├── ImageCreateRequest.java
│       │                   │       │   └── ImageUnderstandingRequest.java
│       │                   │       └── resp/
│       │                   │           ├── ImageCreateResponse.java
│       │                   │           └── ImageUnderstandingResponse.java
│       │                   └── interceptor/
│       │                       ├── BaseUrlInterceptor.java
│       │                       └── ResponseInterceptor.java
│       └── test/
│           └── java/
│               └── com/
│                   └── ai/
│                       └── spark/
│                           ├── AudioApiTest.java
│                           ├── ChatApiTest.java
│                           ├── DocumentApiTest.java
│                           ├── EmbeddingApiTest.java
│                           └── ImageApiTest.java
├── doc/
│   └── test/
│       └── test_file_upload.txt
└── pom.xml
Download .txt
SYMBOL INDEX (644 symbols across 207 files)

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/ApiData.java
  class ApiData (line 12) | @Data

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/Configuration.java
  class Configuration (line 15) | @Data
    method getSystemApiData (line 33) | public ApiData getSystemApiData() {
    method createRequestFactory (line 37) | public EventSource.Factory createRequestFactory() {

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/DefaultBaiduSessionFactory.java
  class DefaultBaiduSessionFactory (line 21) | @AllArgsConstructor
    method createHttpClient (line 26) | @Override
    method createApiServer (line 45) | @Override
    method openAggregationSession (line 55) | @Override

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/DefaultAggregationSession.java
  class DefaultAggregationSession (line 14) | public class DefaultAggregationSession implements AggregationSession {
    method DefaultAggregationSession (line 24) | public DefaultAggregationSession(Configuration configuration) {
    method getChatSession (line 28) | @Override
    method getEmbeddingSession (line 40) | @Override
    method getImageSession (line 52) | @Override

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/DefaultChatSession.java
  class DefaultChatSession (line 25) | @Data
    method DefaultChatSession (line 35) | public DefaultChatSession(Configuration configuration) {
    method chat (line 41) | @Override
    method chat (line 47) | @Override

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/DefaultEmbeddingSession.java
  class DefaultEmbeddingSession (line 20) | @Data
    method DefaultEmbeddingSession (line 25) | public DefaultEmbeddingSession(Configuration configuration) {
    method embedding (line 30) | @Override

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/DefaultImageSession.java
  class DefaultImageSession (line 13) | public class DefaultImageSession extends Session implements ImageSession {
    method DefaultImageSession (line 15) | public DefaultImageSession(Configuration configuration) {
    method text2image (line 20) | @Override

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/Session.java
  class Session (line 10) | @Data
    method checkAccessToken (line 22) | public String checkAccessToken(String accessToken) {

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/standard/api/BaiduApiServer.java
  type BaiduApiServer (line 18) | public interface BaiduApiServer {
    method auth (line 28) | @POST("/oauth/2.0/token")
    method getAccessToken (line 38) | default String getAccessToken(String apiKey, String secretKey) {
    method getAccessToken (line 50) | default String getAccessToken(String grantType, String apiKey, String ...
    method chat (line 61) | @POST("/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro")
    method embedding (line 71) | @POST("/rpc/2.0/ai_custom/v1/wenxinworkshop/embeddings/embedding-v1")
    method text2image (line 81) | @POST("/rpc/2.0/ai_custom/v1/wenxinworkshop/text2image/sd_xl")

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/standard/session/AggregationSession.java
  type AggregationSession (line 6) | public interface AggregationSession {
    method getChatSession (line 11) | ChatSession getChatSession();
    method getEmbeddingSession (line 16) | EmbeddingSession getEmbeddingSession();
    method getImageSession (line 21) | ImageSession getImageSession();

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/standard/session/ChatSession.java
  type ChatSession (line 11) | public interface ChatSession {
    method chat (line 13) | default ChatResponse chat(ChatRequest chatRequest) {
    method chat (line 24) | ChatResponse chat(String accessToken, ChatRequest chatRequest);
    method chat (line 26) | default EventSource chat(ChatRequest chatRequest, EventSourceListener ...
    method chat (line 38) | EventSource chat(String accessToken, ChatRequest chatRequest, EventSou...

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/standard/session/EmbeddingSession.java
  type EmbeddingSession (line 9) | public interface EmbeddingSession {
    method embedding (line 11) | default EmbeddingResponse embedding(EmbeddingRequest embeddingRequest) {
    method embedding (line 22) | EmbeddingResponse embedding(String accessToken, EmbeddingRequest embed...

FILE: ai-baidu/src/main/java/com/ai/baidu/achieve/standard/session/ImageSession.java
  type ImageSession (line 9) | public interface ImageSession {
    method text2image (line 18) | ImageResponse text2image(String accessToken, ImageRequest imageRequest);
    method text2image (line 20) | default ImageResponse text2image(ImageRequest imageRequest) {

FILE: ai-baidu/src/main/java/com/ai/baidu/common/ApiUrl.java
  type ApiUrl (line 9) | @Getter

FILE: ai-baidu/src/main/java/com/ai/baidu/common/Usage.java
  class Usage (line 10) | @Data

FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/auth/resp/AuthResponse.java
  class AuthResponse (line 10) | @Data

FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/chat/Message.java
  class Message (line 7) | @Data
    method baseBuild (line 32) | public static Message baseBuild(Role role, String content) {
    type Role (line 36) | @Getter

FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/chat/SearchResult.java
  class SearchResult (line 9) | @Data

FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/chat/req/ChatRequest.java
  class ChatRequest (line 20) | @Data
    method baseBuild (line 113) | public static ChatRequest baseBuild(Message.Role role, String content) {

FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/chat/resp/ChatResponse.java
  class ChatResponse (line 15) | @Data

FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/embedding/EmbeddingData.java
  class EmbeddingData (line 10) | @Data

FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/embedding/req/EmbeddingRequest.java
  class EmbeddingRequest (line 16) | @Data
    method baseBuild (line 39) | public static EmbeddingRequest baseBuild(List<String> input) {

FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/embedding/resp/EmbeddingResponse.java
  class EmbeddingResponse (line 16) | @Data

FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/images/ImageData.java
  class ImageData (line 10) | @Data

FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/images/req/ImageRequest.java
  class ImageRequest (line 13) | @Data
    method baseBuild (line 119) | public static ImageRequest baseBuild(String prompt) {
    type ImgSize (line 123) | @Getter
    type ImgStyle (line 136) | @Getter

FILE: ai-baidu/src/main/java/com/ai/baidu/endPoint/images/resp/ImageResponse.java
  class ImageResponse (line 14) | @Data

FILE: ai-baidu/src/main/java/com/ai/baidu/interceptor/ResponseInterceptor.java
  class ResponseInterceptor (line 13) | @Slf4j
    method intercept (line 15) | @Override

FILE: ai-baidu/src/test/java/com/ai/baidu/ChatApiTest.java
  class ChatApiTest (line 27) | @Slf4j
    method test_BaiduSessionFactory (line 34) | @Before
    method test_auth (line 60) | @Test
    method test_chat (line 72) | @Test
    method test_chat_multiple (line 82) | @Test
    method test_chat_stream (line 100) | @Test

FILE: ai-baidu/src/test/java/com/ai/baidu/EmbeddingApiTest.java
  class EmbeddingApiTest (line 21) | public class EmbeddingApiTest {
    method test_BaiduSessionFactory (line 27) | @Before
    method test_embedding (line 53) | @Test

FILE: ai-baidu/src/test/java/com/ai/baidu/ImageApiTest.java
  class ImageApiTest (line 22) | public class ImageApiTest {
    method test_BaiduSessionFactory (line 28) | @Before
    method test_text2image (line 51) | @Test

FILE: ai-common/src/main/java/com/ai/common/utils/Exceptions.java
  class Exceptions (line 6) | public class Exceptions {
    method illegalArgument (line 8) | public static IllegalArgumentException illegalArgument(String format, ...
    method runtime (line 12) | public static RuntimeException runtime(String format, Object... args) {

FILE: ai-common/src/main/java/com/ai/common/utils/ImageUtils.java
  class ImageUtils (line 11) | public class ImageUtils {
    method convertImageToBase64Str (line 19) | public static String convertImageToBase64Str(String imageFileName) {
    method convertBase64StrToImage (line 56) | public static void convertBase64StrToImage(String base64String, String...

FILE: ai-common/src/main/java/com/ai/common/utils/JsonUtils.java
  class JsonUtils (line 7) | public class JsonUtils {
    method fromJson (line 11) | public static <T> T fromJson(String json, Class<T> valueType) {
    method toJson (line 20) | public static String toJson(Object object) {

FILE: ai-common/src/main/java/com/ai/common/utils/ValidationUtils.java
  class ValidationUtils (line 8) | public class ValidationUtils {
    method ensureNotNull (line 10) | public static <T> T ensureNotNull(T object, String name) {
    method ensureNotEmpty (line 18) | public static <T extends Collection<?>> T ensureNotEmpty(T collection,...
    method ensureNotBlank (line 26) | public static String ensureNotBlank(String string, String name) {
    method ensureTrue (line 34) | public static void ensureTrue(boolean expression, String msg) {
    method ensureGreaterThanZero (line 40) | public static int ensureGreaterThanZero(Integer i, String name) {
    method ensureBetween (line 48) | public static double ensureBetween(Double d, double min, double max, S...
    method ensureBetween (line 56) | public static int ensureBetween(Integer i, int min, int max, String na...

FILE: ai-core/src/main/java/com/ai/core/config/BaseConfiguration.java
  class BaseConfiguration (line 15) | @Data

FILE: ai-core/src/main/java/com/ai/core/exception/BaseException.java
  class BaseException (line 5) | @Getter
    method BaseException (line 11) | public BaseException(IError error) {
    method BaseException (line 17) | public BaseException(String msg) {
    method BaseException (line 23) | public BaseException() {

FILE: ai-core/src/main/java/com/ai/core/exception/Constants.java
  class Constants (line 12) | public class Constants {
    type ErrorMsg (line 26) | public enum ErrorMsg implements IError {
      method ErrorMsg (line 40) | ErrorMsg(int code, String msg) {
      method msg (line 45) | public String msg() {
      method code (line 49) | public int code() {
    type Role (line 61) | @Getter

FILE: ai-core/src/main/java/com/ai/core/exception/IError.java
  type IError (line 3) | public interface IError {
    method msg (line 5) | String msg();
    method code (line 7) | int code();

FILE: ai-core/src/main/java/com/ai/core/factory/SessionFactory.java
  type SessionFactory (line 6) | public interface SessionFactory<Session, ApiServer> {
    method openAggregationSession (line 13) | Session openAggregationSession();
    method createApiServer (line 21) | ApiServer createApiServer(OkHttpClient okHttpClient);
    method createHttpClient (line 28) | OkHttpClient createHttpClient();

FILE: ai-core/src/main/java/com/ai/core/strategy/KeyStrategy.java
  type KeyStrategy (line 7) | public interface KeyStrategy<T, R> {
    method apply (line 8) | R apply(T t);

FILE: ai-core/src/main/java/com/ai/core/strategy/impl/FirstKeyStrategy.java
  class FirstKeyStrategy (line 8) | public class FirstKeyStrategy<T> implements KeyStrategy<List<T>, T> {
    method apply (line 10) | @Override

FILE: ai-core/src/main/java/com/ai/core/strategy/impl/RandomKeyStrategy.java
  class RandomKeyStrategy (line 9) | public class RandomKeyStrategy<T> implements KeyStrategy<List<T>, T> {
    method apply (line 11) | @Override

FILE: ai-openai/src/main/java/com/ai/openai/Product.java
  class Product (line 3) | public class Product {
    method Product (line 8) | public Product(Builder builder) {
    method main (line 13) | public static void main(String[] args) {
    class Builder (line 17) | public static class Builder {
      method Builder (line 21) | public Builder() {
      method setStr1 (line 24) | public Builder setStr1(String str1) {
      method setStr2 (line 29) | public Builder setStr2(String str2) {
      method build (line 34) | public Product build() {

FILE: ai-openai/src/main/java/com/ai/openai/Singleton.java
  class Singleton (line 4) | public class Singleton {
    method Singleton (line 8) | private Singleton() {
    method getInstance (line 11) | public static Singleton getInstance() {

FILE: ai-openai/src/main/java/com/ai/openai/ThreadPrint.java
  class LockPrinter (line 8) | class LockPrinter {
    method main (line 13) | public static void main(String[] args) {
    method printNumber (line 19) | public static void printNumber(int target) {
  class SyncPrinter (line 38) | class SyncPrinter {
    method main (line 42) | public static void main(String[] args) {
    method printNumber (line 48) | public static void printNumber(int target) {

FILE: ai-openai/src/main/java/com/ai/openai/achieve/Configuration.java
  class Configuration (line 15) | @Data
    method createRequestFactory (line 33) | public EventSource.Factory createRequestFactory() {
    method getSystemApiData (line 38) | public String getSystemApiData() {

FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/DefaultOpenAiSessionFactory.java
  class DefaultOpenAiSessionFactory (line 23) | @AllArgsConstructor
    method createHttpClient (line 28) | @Override
    method createApiServer (line 48) | @Override
    method openAggregationSession (line 58) | @Override

FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultAggregationSession.java
  class DefaultAggregationSession (line 11) | public class DefaultAggregationSession implements AggregationSession {
    method DefaultAggregationSession (line 31) | public DefaultAggregationSession(Configuration configuration) {
    method getConfiguration (line 35) | public Configuration getConfiguration() {
    method getAudioSession (line 39) | @Override
    method getChatSession (line 51) | @Override
    method getFineTuningSession (line 63) | @Override
    method getEmbeddingSession (line 75) | @Override
    method getFilesSession (line 87) | @Override
    method getImageSession (line 99) | @Override
    method getModelSession (line 111) | @Override
    method getModerationSession (line 123) | @Override

FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultAudioSession.java
  class DefaultAudioSession (line 26) | @Data
    method DefaultAudioSession (line 31) | public DefaultAudioSession(Configuration configuration) {
    method ttsCompletions (line 36) | @Override
    method sttBaseCompletions (line 41) | private SttCompletionResponse sttBaseCompletions(String apiHostByUser,...
    method sttCompletions (line 66) | @Override
    method translationCompletions (line 71) | @Override

FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultChatSession.java
  class DefaultChatSession (line 40) | @Data
    method DefaultChatSession (line 50) | public DefaultChatSession(Configuration configuration) {
    method qaCompletions (line 56) | @Override
    method qaCompletions (line 61) | @Override
    method chatCompletions (line 73) | @Override
    method chatCompletions (line 78) | @Override
    method chatCompletions (line 83) | @Override
    method chatCompletions (line 88) | @Override
    method chatCompletionsFuture (line 100) | @Override

FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultEmbeddingSession.java
  class DefaultEmbeddingSession (line 21) | @Data
    method DefaultEmbeddingSession (line 26) | public DefaultEmbeddingSession(Configuration configuration) {
    method embeddingCompletions (line 31) | @Override
    method embeddingCompletions (line 36) | @Override
    method embeddingCompletions (line 41) | @Override

FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultFilesSession.java
  class DefaultFilesSession (line 23) | @Data
    method DefaultFilesSession (line 28) | public DefaultFilesSession(Configuration configuration) {
    method listFilesCompletions (line 33) | @Override
    method uploadFileCompletions (line 38) | @Override
    method deleteFileCompletions (line 46) | @Override
    method retrieveFileCompletions (line 51) | @Override
    method retrieveFileContextCompletions (line 56) | @Override

FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultFineTuningSession.java
  class DefaultFineTuningSession (line 19) | @Data
    method DefaultFineTuningSession (line 24) | public DefaultFineTuningSession(Configuration configuration) {
    method createFineTuningJobCompletions (line 29) | @Override
    method listFineTuningJobsCompletions (line 34) | @Override
    method listFineTuningJobsCompletions (line 39) | @Override
    method retrieveFineTuningJobCompletions (line 44) | @Override
    method cancelFineTuningJobCompletions (line 49) | @Override
    method listFineTuningEventsCompletions (line 54) | @Override

FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultImageSession.java
  class DefaultImageSession (line 27) | @Data
    method DefaultImageSession (line 32) | public DefaultImageSession(Configuration configuration) {
    method createImageCompletions (line 37) | @Override
    method editImageCompletions (line 42) | @Override
    method variationImageCompletions (line 68) | @Override

FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultModelSession.java
  class DefaultModelSession (line 19) | @Data
    method DefaultModelSession (line 24) | public DefaultModelSession(Configuration configuration) {
    method listModelCompletions (line 29) | @Override
    method retrieveModelCompletions (line 34) | @Override
    method deleteFineTuneModelCompletions (line 39) | @Override

FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultModerationSession.java
  class DefaultModerationSession (line 21) | @Data
    method DefaultModerationSession (line 26) | public DefaultModerationSession(Configuration configuration) {
    method moderationCompletions (line 31) | @Override

FILE: ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/Session.java
  class Session (line 8) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/api/OpenaiApiServer.java
  type OpenaiApiServer (line 39) | public interface OpenaiApiServer {
    method createQaCompletion (line 50) | @POST("/v1/completions")
    method createChatCompletion (line 62) | @POST("/v1/chat/completions")
    method createChatCompletion (line 74) | @POST("/v1/chat/completions")
    method createChatCompletion (line 86) | @POST("/v1/chat/completions")
    method createSpeechCompletion (line 99) | @POST("/v1/audio/speech")
    method createTranscriptionCompletion (line 113) | @Multipart
    method createTranslationCompletion (line 127) | @Multipart
    method createEmbeddingsCompletion (line 140) | @POST("/v1/embeddings")
    method createFineTuningJobCompletion (line 152) | @POST("/v1/fine_tuning/jobs")
    method listFineTuningJobsCompletion (line 165) | @GET("/v1/fine_tuning/jobs")
    method retrieveFineTuningJobCompletion (line 177) | @GET("/v1/fine_tuning/jobs/{fine_tuning_job_id}")
    method cancelFineTuningJobCompletion (line 189) | @POST("/v1/fine_tuning/jobs/{fine_tuning_job_id}/cancel")
    method listFineTuningEventsCompletion (line 201) | @GET("/v1/fine_tuning/jobs/{fine_tuning_job_id}/events")
    method listFilesCompletion (line 212) | @GET("/v1/files")
    method uploadFileCompletion (line 225) | @Multipart
    method deleteFileCompletion (line 238) | @DELETE("/v1/files/{file_id}")
    method retrieveFileCompletion (line 250) | @GET("/v1/files/{file_id}")
    method retrieveFileContentCompletion (line 263) | @Streaming
    method createImageCompletion (line 276) | @POST("/v1/images/generations")
    method editImageCompletion (line 290) | @Multipart
    method variationImageCompletion (line 307) | @Multipart
    method listModelsCompletion (line 322) | @GET("/v1/models")
    method retrieveModelCompletion (line 334) | @GET("/v1/models/{model}")
    method deleteFineTuneModelCompletion (line 346) | @DELETE("/v1/models/{model}")
    method moderationCompletion (line 359) | @POST("/v1/moderations")

FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/AggregationSession.java
  type AggregationSession (line 6) | public interface AggregationSession {
    method getAudioSession (line 11) | AudioSession getAudioSession();
    method getChatSession (line 16) | ChatSession getChatSession();
    method getFineTuningSession (line 21) | FineTuningSession getFineTuningSession();
    method getEmbeddingSession (line 26) | EmbeddingSession getEmbeddingSession();
    method getFilesSession (line 31) | FilesSession getFilesSession();
    method getImageSession (line 36) | ImageSession getImageSession();
    method getModelSession (line 41) | ModelSession getModelSession();
    method getModerationSession (line 46) | ModerationSession getModerationSession();

FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/AudioSession.java
  type AudioSession (line 11) | public interface AudioSession {
    method ttsCompletions (line 22) | void ttsCompletions(String apiHostByUser, String apiKeyByUser, String ...
    method sttCompletions (line 33) | SttCompletionResponse sttCompletions(String apiHostByUser, String apiK...
    method translationCompletions (line 44) | SttCompletionResponse translationCompletions(String apiHostByUser, Str...

FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/ChatSession.java
  type ChatSession (line 18) | public interface ChatSession {
    method qaCompletions (line 29) | QaCompletionResponse qaCompletions(String apiHostByUser, String apiKey...
    method qaCompletions (line 41) | EventSource qaCompletions(String apiHostByUser, String apiKeyByUser, S...
    method chatCompletions (line 52) | ChatCompletionResponse chatCompletions(String apiHostByUser, String ap...
    method chatCompletions (line 63) | ChatCompletionResponse chatCompletions(String apiHostByUser, String ap...
    method chatCompletions (line 74) | ChatCompletionResponse chatCompletions(String apiHostByUser, String ap...
    method chatCompletions (line 86) | EventSource chatCompletions(String apiHostByUser, String apiKeyByUser,...
    method chatCompletionsFuture (line 94) | CompletableFuture<String> chatCompletionsFuture(String apiHostByUser, ...

FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/EmbeddingSession.java
  type EmbeddingSession (line 11) | public interface EmbeddingSession {
    method embeddingCompletions (line 22) | EmbeddingCompletionResponse embeddingCompletions(String apiHostByUser,...
    method embeddingCompletions (line 33) | EmbeddingCompletionResponse embeddingCompletions(String apiHostByUser,...
    method embeddingCompletions (line 44) | EmbeddingCompletionResponse embeddingCompletions(String apiHostByUser,...

FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/FilesSession.java
  type FilesSession (line 13) | public interface FilesSession {
    method listFilesCompletions (line 22) | List<FileObject> listFilesCompletions(String apiHostByUser, String api...
    method uploadFileCompletions (line 34) | FileObject uploadFileCompletions(String apiHostByUser, String apiKeyBy...
    method deleteFileCompletions (line 45) | DeleteFileResponse deleteFileCompletions(String apiHostByUser, String ...
    method retrieveFileCompletions (line 56) | FileObject retrieveFileCompletions(String apiHostByUser, String apiKey...
    method retrieveFileContextCompletions (line 67) | ResponseBody retrieveFileContextCompletions(String apiHostByUser, Stri...

FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/FineTuningSession.java
  type FineTuningSession (line 12) | public interface FineTuningSession {
    method createFineTuningJobCompletions (line 23) | FineTuningResponse createFineTuningJobCompletions(String apiHostByUser...
    method listFineTuningJobsCompletions (line 34) | CommonListResponse<FineTuningResponse> listFineTuningJobsCompletions(S...
    method listFineTuningJobsCompletions (line 46) | CommonListResponse<FineTuningResponse> listFineTuningJobsCompletions(S...
    method retrieveFineTuningJobCompletions (line 57) | FineTuningResponse retrieveFineTuningJobCompletions(String apiHostByUs...
    method cancelFineTuningJobCompletions (line 68) | FineTuningResponse cancelFineTuningJobCompletions(String apiHostByUser...
    method listFineTuningEventsCompletions (line 79) | CommonListResponse<FineTuningEvent> listFineTuningEventsCompletions(St...

FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/ImageSession.java
  type ImageSession (line 14) | public interface ImageSession {
    method createImageCompletions (line 23) | List<ImageObject> createImageCompletions(String apiHostByUser, String ...
    method editImageCompletions (line 36) | List<ImageObject> editImageCompletions(String apiHostByUser, String ap...
    method variationImageCompletions (line 48) | List<ImageObject> variationImageCompletions(String apiHostByUser, Stri...

FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/ModelSession.java
  type ModelSession (line 12) | public interface ModelSession {
    method listModelCompletions (line 22) | List<ModelObject> listModelCompletions(String apiHostByUser, String ap...
    method retrieveModelCompletions (line 33) | ModelObject retrieveModelCompletions(String apiHostByUser, String apiK...
    method deleteFineTuneModelCompletions (line 44) | DeleteFineTuneModelResponse deleteFineTuneModelCompletions(String apiH...

FILE: ai-openai/src/main/java/com/ai/openai/achieve/standard/session/ModerationSession.java
  type ModerationSession (line 10) | public interface ModerationSession {
    method moderationCompletions (line 20) | ModerationResponse moderationCompletions(String apiHostByUser, String ...

FILE: ai-openai/src/main/java/com/ai/openai/common/ApiUrl.java
  type ApiUrl (line 9) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/common/CommonListResponse.java
  class CommonListResponse (line 15) | @Data
    class Error (line 25) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/common/Usage.java
  class Usage (line 8) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/audio/req/SttCompletionRequest.java
  class SttCompletionRequest (line 12) | @Data
    type Model (line 58) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/audio/req/TtsCompletionRequest.java
  class TtsCompletionRequest (line 11) | @Data
    method baseBuild (line 54) | public static TtsCompletionRequest baseBuild(String input) {
    type Model (line 63) | @Getter
    type Voice (line 73) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/audio/resp/SttCompletionResponse.java
  class SttCompletionResponse (line 12) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/ChatChoice.java
  class ChatChoice (line 16) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/Parameters.java
  class Parameters (line 11) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/QaChoice.java
  class QaChoice (line 13) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/ResponseFormat.java
  class ResponseFormat (line 10) | @Data
    type Type (line 21) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/BaseMessage.java
  class BaseMessage (line 15) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/Content.java
  class Content (line 10) | @Data
    method BuildTextContent (line 36) | public static Content BuildTextContent(String text) {
    method BuildImageUrlContent (line 43) | public static Content BuildImageUrlContent(String urlOrB64Json) {
    type Type (line 50) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/DefaultMessage.java
  class DefaultMessage (line 18) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/ImageUrl.java
  class ImageUrl (line 12) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/ImgMessage.java
  class ImgMessage (line 15) | @Data
    method addTextContent (line 30) | public void addTextContent(String text) {
    method addImageContent (line 37) | public void addImageContent(String imageUrl) {
    method addContent (line 47) | public void addContent(Content content) {

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/BaseChatCompletionRequest.java
  class BaseChatCompletionRequest (line 14) | @Data
    type Model (line 91) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/DefaultChatCompletionRequest.java
  class DefaultChatCompletionRequest (line 21) | @Data
    method baseBuild (line 45) | public static DefaultChatCompletionRequest baseBuild(String question) {
    method addMessage (line 57) | public void addMessage(DefaultMessage message) {
    method addMessage (line 67) | public void addMessage(String role, String content) {

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/FuncChatCompletionRequest.java
  class FuncChatCompletionRequest (line 23) | @Data
    method baseBuild (line 53) | public static FuncChatCompletionRequest baseBuild(String question) {
    method addMessage (line 64) | public void addMessage(DefaultMessage message) {
    method addMessage (line 74) | public void addMessage(String role, String content) {

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/ImgChatCompletionRequest.java
  class ImgChatCompletionRequest (line 18) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/QaCompletionRequest.java
  class QaCompletionRequest (line 12) | @Builder
    method baseBuild (line 111) | public static QaCompletionRequest baseBuild(String question) {
    type Model (line 115) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/resp/ChatCompletionResponse.java
  class ChatCompletionResponse (line 18) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/resp/QaCompletionResponse.java
  class QaCompletionResponse (line 18) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/tools/Tool.java
  class Tool (line 7) | @Data
    type Type (line 22) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/tools/ToolCall.java
  class ToolCall (line 10) | @Data
    type Type (line 22) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/tools/ToolCallFunction.java
  class ToolCallFunction (line 13) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/chat/tools/ToolFunction.java
  class ToolFunction (line 11) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/embeddings/EmbeddingObject.java
  class EmbeddingObject (line 11) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/embeddings/req/EmbeddingCompletionRequest.java
  class EmbeddingCompletionRequest (line 12) | @Data
    method baseBuild (line 50) | public static EmbeddingCompletionRequest baseBuild(String input) {
    method baseBuild (line 60) | public static EmbeddingCompletionRequest baseBuild(List<String> inputL...
    type Model (line 64) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/embeddings/resp/EmbeddingCompletionResponse.java
  class EmbeddingCompletionResponse (line 14) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/files/FileObject.java
  class FileObject (line 10) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/files/resp/DeleteFileResponse.java
  class DeleteFileResponse (line 12) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/FineTuneError.java
  class FineTuneError (line 9) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/FineTuningEvent.java
  class FineTuningEvent (line 10) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/HyperParameters.java
  class HyperParameters (line 13) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/req/FineTuningRequest.java
  class FineTuningRequest (line 11) | @Data
    type Model (line 49) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/req/ListFineTuningRequest.java
  class ListFineTuningRequest (line 12) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/resp/FineTuningResponse.java
  class FineTuningResponse (line 14) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/images/ImageObject.java
  class ImageObject (line 8) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/images/req/CreateImageRequest.java
  class CreateImageRequest (line 10) | @Data
    method baseBuild (line 79) | public static CreateImageRequest baseBuild(String prompt) {
    type Model (line 86) | @Getter
    type Quality (line 98) | @Getter
    type Style (line 110) | @Getter
    type Format (line 119) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/images/req/ImageEditRequest.java
  class ImageEditRequest (line 10) | @Data
    method baseBuild (line 50) | public static ImageEditRequest baseBuild(String prompt) {
    type SizeEnum (line 54) | @Getter
    type ResponseFormat (line 67) | @AllArgsConstructor

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/images/req/ImageVariationRequest.java
  class ImageVariationRequest (line 11) | @Slf4j
    type SizeEnum (line 39) | @Getter
    type ResponseFormat (line 52) | @AllArgsConstructor

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/images/resp/CreateImageResponse.java
  class CreateImageResponse (line 12) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/models/ModelObject.java
  class ModelObject (line 9) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/models/resp/DeleteFineTuneModelResponse.java
  class DeleteFineTuneModelResponse (line 11) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/moderations/Categories.java
  class Categories (line 11) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/moderations/CategoryScores.java
  class CategoryScores (line 11) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/moderations/Result.java
  class Result (line 12) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/moderations/req/ModerationRequest.java
  class ModerationRequest (line 10) | @Data
    method baseBuild (line 30) | public static ModerationRequest baseBuild(String input) {
    method baseBuild (line 42) | public static ModerationRequest baseBuild(List<String> inputList) {
    type Model (line 46) | @Getter

FILE: ai-openai/src/main/java/com/ai/openai/endPoint/moderations/resp/ModerationResponse.java
  class ModerationResponse (line 12) | @Data

FILE: ai-openai/src/main/java/com/ai/openai/interceptor/HeaderInterceptor.java
  class HeaderInterceptor (line 19) | public class HeaderInterceptor implements Interceptor {
    method HeaderInterceptor (line 36) | public HeaderInterceptor(List<String> apiKeyBySystem, String apiHostBy...
    method intercept (line 42) | @NotNull

FILE: ai-openai/src/main/java/com/ai/openai/interceptor/ResponseInterceptor.java
  class ResponseInterceptor (line 15) | @Slf4j
    method intercept (line 17) | @Override

FILE: ai-openai/src/test/java/com/ai/openai/AudioApiTest.java
  class AudioApiTest (line 29) | @Slf4j
    method test_OpenAiSessionFactory (line 34) | @Before
    method test_tts (line 55) | @Test
    method test_stt (line 99) | @Test
    method test_translation (line 111) | @Test

FILE: ai-openai/src/test/java/com/ai/openai/ChatApiTest.java
  class ChatApiTest (line 39) | @Slf4j
    method test_OpenAiSessionFactory (line 44) | @Before
    method test_qa_completions (line 65) | @Test
    method test_qa_completions_stream (line 75) | @Test
    method test_chat_completions (line 100) | @Test
    method test_func_chat_completions (line 121) | @Test
    method test_img_chat_completions (line 153) | @Test
    method test_chat_completions_stream (line 170) | @Test
    method test_chat_completions_future (line 201) | @Test

FILE: ai-openai/src/test/java/com/ai/openai/EmbeddingApiTest.java
  class EmbeddingApiTest (line 25) | @Slf4j
    method test_OpenAiSessionFactory (line 30) | @Before
    method test_embedding (line 51) | @Test
    method test_embedding_list (line 65) | @Test
    method test_embedding_req (line 74) | @Test

FILE: ai-openai/src/test/java/com/ai/openai/FilesApiTest.java
  class FilesApiTest (line 25) | @Slf4j
    method test_OpenAiSessionFactory (line 30) | @Before
    method test_list_file (line 51) | @Test
    method test_upload_file (line 60) | @Test
    method test_delete_file (line 70) | @Test
    method test_retrieve_file (line 79) | @Test
    method test_retrieve_file_context (line 88) | @Test

FILE: ai-openai/src/test/java/com/ai/openai/FineTuningApiTest.java
  class FineTuningApiTest (line 25) | @Slf4j
    method test_OpenAiSessionFactory (line 30) | @Before
    method test_create_fine_tuning (line 51) | @Test
    method test_list_fine_tuning_1 (line 64) | @Test
    method test_list_fine_tuning_2 (line 74) | @Test
    method test_retrieve_fine_tuning (line 83) | @Test
    method test_cancel_fine_tuning (line 92) | @Test
    method test_list_fine_tuning_events (line 101) | @Test

FILE: ai-openai/src/test/java/com/ai/openai/ImageApiTest.java
  class ImageApiTest (line 27) | @Slf4j
    method test_OpenAiSessionFactory (line 31) | @Before
    method test_create_image_b64json (line 52) | @Test
    method test_create_image_url (line 65) | @Test
    method test_edit_image (line 78) | @Test
    method test_variation_image (line 89) | @Test

FILE: ai-openai/src/test/java/com/ai/openai/ModelApiTest.java
  class ModelApiTest (line 23) | @Slf4j
    method test_OpenAiSessionFactory (line 28) | @Before
    method test_list_model (line 49) | @Test
    method test_retrieve_model (line 58) | @Test
    method test_delete_fine_tune_model (line 67) | @Test

FILE: ai-openai/src/test/java/com/ai/openai/ModerationApiTest.java
  class ModerationApiTest (line 24) | @Slf4j
    method test_OpenAiSessionFactory (line 29) | @Before
    method test_moderation (line 50) | @Test

FILE: ai-spark/src/main/java/com/ai/spark/achieve/ApiData.java
  class ApiData (line 12) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/achieve/Configuration.java
  class Configuration (line 13) | @Data
    method getSystemApiData (line 31) | public ApiData getSystemApiData() {

FILE: ai-spark/src/main/java/com/ai/spark/achieve/defaults/DefaultSparkSessionFactory.java
  class DefaultSparkSessionFactory (line 20) | public class DefaultSparkSessionFactory implements SessionFactory<Aggreg...
    method DefaultSparkSessionFactory (line 24) | public DefaultSparkSessionFactory(Configuration configuration) {
    method createHttpClient (line 28) | @Override
    method createApiServer (line 48) | @Override
    method openAggregationSession (line 58) | @Override

FILE: ai-spark/src/main/java/com/ai/spark/achieve/defaults/listener/BaseListener.java
  class BaseListener (line 12) | @Slf4j
    method onWebSocketError (line 23) | public void onWebSocketError(Throwable t, Response response) {
    method onChatError (line 33) | public abstract void onChatError(RESP resp);
    method onChatOutput (line 40) | public abstract void onChatOutput(RESP resp);
    method onChatEnd (line 45) | public abstract void onChatEnd();
    method onClosed (line 47) | @Override
    method onClosing (line 52) | @Override
    method onFailure (line 57) | @Override
    method onMessage (line 63) | @Override
    method onMessage (line 66) | @Override
    method onOpen (line 71) | @Override

FILE: ai-spark/src/main/java/com/ai/spark/achieve/defaults/listener/ChatListener.java
  class ChatListener (line 22) | @Slf4j
    method ChatListener (line 28) | public ChatListener(ChatRequest chatRequest) {
    method onWebSocketError (line 39) | public void onWebSocketError(Throwable t, Response response) {
    method onChatError (line 49) | public abstract void onChatError(ChatResponse chatResponse);
    method onChatOutput (line 56) | public abstract void onChatOutput(ChatResponse chatResponse);
    method onChatEnd (line 61) | public abstract void onChatEnd();
    method onClosed (line 63) | @Override
    method onClosing (line 68) | @Override
    method onFailure (line 73) | @Override
    method onMessage (line 79) | @Override
    method onMessage (line 100) | @Override
    method onOpen (line 105) | @Override

FILE: ai-spark/src/main/java/com/ai/spark/achieve/defaults/listener/DocumentChatListener.java
  class DocumentChatListener (line 19) | @Slf4j
    method DocumentChatListener (line 30) | public DocumentChatListener(DocumentChatRequest documentChatRequest) {
    method onWebSocketError (line 41) | public void onWebSocketError(Throwable t, Response response) {
    method onChatError (line 51) | public abstract void onChatError(DocumentChatResponse documentChatResp...
    method onChatOutput (line 58) | public abstract void onChatOutput(DocumentChatResponse documentChatRes...
    method onChatEnd (line 63) | public abstract void onChatEnd();
    method onClosed (line 65) | @Override
    method onClosing (line 70) | @Override
    method onFailure (line 75) | @Override
    method onMessage (line 81) | @Override
    method onMessage (line 101) | @Override
    method onOpen (line 106) | @Override

FILE: ai-spark/src/main/java/com/ai/spark/achieve/defaults/listener/ImageUnderstandingListener.java
  class ImageUnderstandingListener (line 23) | @Slf4j
    method ImageUnderstandingListener (line 34) | public ImageUnderstandingListener(ImageUnderstandingRequest imageUnder...
    method onWebSocketError (line 45) | public void onWebSocketError(Throwable t, Response response) {
    method onChatError (line 55) | public abstract void onChatError(ImageUnderstandingResponse imageUnder...
    method onChatOutput (line 62) | public abstract void onChatOutput(ImageUnderstandingResponse imageUnde...
    method onChatEnd (line 67) | public abstract void onChatEnd();
    method onClosed (line 69) | @Override
    method onClosing (line 74) | @Override
    method onFailure (line 79) | @Override
    method onMessage (line 85) | @Override
    method onMessage (line 106) | @Override
    method onOpen (line 111) | @Override

FILE: ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/DefaultAggregationSession.java
  class DefaultAggregationSession (line 11) | public class DefaultAggregationSession implements AggregationSession {
    method DefaultAggregationSession (line 25) | public DefaultAggregationSession(Configuration configuration) {
    method getChatSession (line 29) | @Override
    method getDocumentSession (line 41) | @Override
    method getEmbeddingSession (line 53) | @Override
    method getImageSession (line 65) | @Override
    method getAudioSession (line 77) | @Override

FILE: ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/DefaultAudioSession.java
  class DefaultAudioSession (line 11) | @Data
    method DefaultAudioSession (line 16) | public DefaultAudioSession(Configuration configuration) {

FILE: ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/DefaultChatSession.java
  class DefaultChatSession (line 22) | @Data
    method DefaultChatSession (line 27) | public DefaultChatSession(Configuration configuration) {
    method chat (line 32) | @Override
    method chat (line 40) | @Override
    method documentChat (line 53) | @Override
    method documentChat (line 59) | @Override

FILE: ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/DefaultDocumentSession.java
  class DefaultDocumentSession (line 25) | @Data
    method DefaultDocumentSession (line 30) | public DefaultDocumentSession(Configuration configuration) {
    method fileUpload (line 35) | @Override
    method fileUpload (line 41) | @Override
    method documentSummaryStart (line 66) | @Override
    method documentSummaryStart (line 72) | @Override
    method documentSummaryQuery (line 77) | @Override
    method documentSummaryQuery (line 83) | @Override
    method documentSummary (line 97) | private DocumentSummaryResponse documentSummary(String url, String app...

FILE: ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/DefaultEmbeddingSession.java
  class DefaultEmbeddingSession (line 22) | @Data
    method DefaultEmbeddingSession (line 28) | public DefaultEmbeddingSession(Configuration configuration) {
    method embed (line 33) | @Override
    method embed (line 39) | @Override

FILE: ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/DefaultImageSession.java
  class DefaultImageSession (line 25) | @Data
    method DefaultImageSession (line 30) | public DefaultImageSession(Configuration configuration) {
    method imageCreate (line 35) | @Override
    method imageCreate (line 42) | @Override
    method imageUnderstanding (line 55) | @Override
    method imageUnderstanding (line 61) | @Override

FILE: ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/Session.java
  class Session (line 7) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/achieve/standard/api/SparkApiServer.java
  type SparkApiServer (line 19) | public interface SparkApiServer {
    method fileUpload (line 31) | @Multipart
    method documentSummary (line 45) | @Multipart

FILE: ai-spark/src/main/java/com/ai/spark/achieve/standard/session/AggregationSession.java
  type AggregationSession (line 4) | public interface AggregationSession {
    method getChatSession (line 6) | ChatSession getChatSession();
    method getDocumentSession (line 8) | DocumentSession getDocumentSession();
    method getEmbeddingSession (line 10) | EmbeddingSession getEmbeddingSession();
    method getImageSession (line 12) | ImageSession getImageSession();
    method getAudioSession (line 14) | AudioSession getAudioSession();

FILE: ai-spark/src/main/java/com/ai/spark/achieve/standard/session/AudioSession.java
  type AudioSession (line 4) | public interface AudioSession {

FILE: ai-spark/src/main/java/com/ai/spark/achieve/standard/session/ChatSession.java
  type ChatSession (line 11) | public interface ChatSession {
    method chat (line 19) | <T extends ChatListener> WebSocket chat(T chatListener);
    method chat (line 29) | <T extends ChatListener> WebSocket chat(String apiKey, String apiSecre...
    method documentChat (line 37) | <T extends DocumentChatListener> WebSocket documentChat(T documentChat...
    method documentChat (line 47) | <T extends DocumentChatListener> WebSocket documentChat(String appId, ...

FILE: ai-spark/src/main/java/com/ai/spark/achieve/standard/session/DocumentSession.java
  type DocumentSession (line 11) | public interface DocumentSession {
    method fileUpload (line 19) | FileUploadResponse fileUpload(FileUploadRequest fileUploadRequest);
    method fileUpload (line 29) | FileUploadResponse fileUpload(String appId, String apiSecret, FileUplo...
    method documentSummaryStart (line 37) | DocumentSummaryResponse documentSummaryStart(String fileId);
    method documentSummaryStart (line 47) | DocumentSummaryResponse documentSummaryStart(String appId, String apiS...
    method documentSummaryQuery (line 55) | DocumentSummaryResponse documentSummaryQuery(String fileId);
    method documentSummaryQuery (line 65) | DocumentSummaryResponse documentSummaryQuery(String appId, String apiS...

FILE: ai-spark/src/main/java/com/ai/spark/achieve/standard/session/EmbeddingSession.java
  type EmbeddingSession (line 10) | public interface EmbeddingSession {
    method embed (line 18) | EmbeddingResponse embed(EmbeddingRequest embeddingRequest);
    method embed (line 28) | EmbeddingResponse embed(String apiKey, String apiSecret, EmbeddingRequ...

FILE: ai-spark/src/main/java/com/ai/spark/achieve/standard/session/ImageSession.java
  type ImageSession (line 13) | public interface ImageSession {
    method imageCreate (line 21) | ImageCreateResponse imageCreate(ImageCreateRequest imageCreateRequest);
    method imageCreate (line 31) | ImageCreateResponse imageCreate(String apiKey, String apiSecret, Image...
    method imageUnderstanding (line 39) | public <T extends ImageUnderstandingListener> WebSocket imageUnderstan...
    method imageUnderstanding (line 49) | public <T extends ImageUnderstandingListener> WebSocket imageUnderstan...

FILE: ai-spark/src/main/java/com/ai/spark/common/Constants.java
  class Constants (line 4) | public class Constants {

FILE: ai-spark/src/main/java/com/ai/spark/common/SparkApiUrl.java
  class SparkApiUrl (line 13) | @Slf4j
    method getUrl (line 77) | public static String getUrl(String key) {
    type ApiUrl (line 85) | @Getter

FILE: ai-spark/src/main/java/com/ai/spark/common/Usage.java
  class Usage (line 10) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/common/UsageText.java
  class UsageText (line 10) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/common/utils/AuthUtils.java
  class AuthUtils (line 27) | public class AuthUtils {
    method replaceAllHttp (line 38) | public static String replaceAllHttp(String authUrl) {
    method getAuthUrl (line 51) | public static String getAuthUrl(String requestMethod, String hostUrl, ...
    method getSignature (line 74) | public static String getSignature(String appId, String secret, long ts) {
    method hmacSHA1Encrypt (line 90) | private static String hmacSHA1Encrypt(String encryptText, String encry...
    method md5 (line 110) | private static String md5(String cipherText) {
    type RequestMethod (line 137) | @Getter

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/audio/Audio.java
  class Audio (line 11) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/audio/AudioHeader.java
  class AudioHeader (line 11) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/audio/AudioParameter.java
  class AudioParameter (line 10) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/audio/AudioPayload.java
  class AudioPayload (line 11) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/audio/AudioText.java
  class AudioText (line 10) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/audio/Oral.java
  class Oral (line 11) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/audio/Pybuf.java
  class Pybuf (line 10) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/audio/Tts.java
  class Tts (line 7) | @Data
    type Vcn (line 92) | @Getter

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/audio/req/AudioRequest.java
  class AudioRequest (line 14) | @Data
    method baseBuild (line 34) | public static AudioRequest baseBuild(Tts.Vcn vcn, String appId) {

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/audio/resp/AudioResponse.java
  class AudioResponse (line 12) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/Chat.java
  class Chat (line 8) | @Data
    type General (line 55) | @Getter

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/ChatHeader.java
  class ChatHeader (line 8) | @Data
    type Code (line 50) | @Getter

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/ChatParameter.java
  class ChatParameter (line 10) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/ChatPayload.java
  class ChatPayload (line 13) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/ChatText.java
  class ChatText (line 8) | @Data
    method baseBuild (line 40) | public static ChatText baseBuild(Role role, String content) {
    type Role (line 44) | @Getter
    type ContentType (line 55) | @Getter

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/Choice.java
  class Choice (line 11) | @Data
    type Status (line 32) | @Getter
      method Status (line 41) | Status(int value) {

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/Message.java
  class Message (line 13) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/document/ChatExtends.java
  class ChatExtends (line 10) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/function/Function.java
  class Function (line 12) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/function/FunctionParameter.java
  class FunctionParameter (line 11) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/function/FunctionText.java
  class FunctionText (line 10) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/req/ChatRequest.java
  class ChatRequest (line 15) | @Data
    method baseBuild (line 30) | public static ChatRequest baseBuild(String question, String appId) {

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/req/DocumentChatRequest.java
  class DocumentChatRequest (line 17) | @Data
    method baseBuild (line 39) | public static DocumentChatRequest baseBuild(String question, List<Stri...

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/resp/ChatResponse.java
  class ChatResponse (line 13) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/chat/resp/DocumentChatResponse.java
  class DocumentChatResponse (line 7) | @Data
    type Code (line 40) | @Getter
    type Status (line 49) | @Getter
      method Status (line 59) | Status(int value) {

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/document/Data.java
  class Data (line 9) | @lombok.Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/document/req/FileUploadRequest.java
  class FileUploadRequest (line 10) | @Data
    type FileType (line 41) | @Getter

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/document/resp/DocumentSummaryResponse.java
  class DocumentSummaryResponse (line 10) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/document/resp/FileUploadResponse.java
  class FileUploadResponse (line 10) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/embedding/Emb.java
  class Emb (line 11) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/embedding/EmbeddingHeader.java
  class EmbeddingHeader (line 12) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/embedding/EmbeddingMessage.java
  class EmbeddingMessage (line 11) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/embedding/EmbeddingParameter.java
  class EmbeddingParameter (line 11) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/embedding/EmbeddingPayload.java
  class EmbeddingPayload (line 12) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/embedding/Feature.java
  class Feature (line 11) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/embedding/req/EmbeddingRequest.java
  class EmbeddingRequest (line 21) | @Data
    method baseBuild (line 40) | public static EmbeddingRequest baseBuild(ChatText text, String appId) {

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/embedding/resp/EmbeddingResponse.java
  class EmbeddingResponse (line 14) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/images/ImageChat.java
  class ImageChat (line 11) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/images/ImageHeader.java
  class ImageHeader (line 12) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/images/ImageParameter.java
  class ImageParameter (line 13) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/images/ImagePayload.java
  class ImagePayload (line 14) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/images/ImageUnderstandingChat.java
  class ImageUnderstandingChat (line 12) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/images/ImageUnderstandingParameter.java
  class ImageUnderstandingParameter (line 12) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/images/ImageUnderstandingPayload.java
  class ImageUnderstandingPayload (line 15) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/images/req/ImageCreateRequest.java
  class ImageCreateRequest (line 19) | @Data
    method baseBuild (line 37) | public static ImageCreateRequest baseBuild(String content, String appI...

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/images/req/ImageUnderstandingRequest.java
  class ImageUnderstandingRequest (line 25) | @Data
    method baseBuild (line 43) | public static ImageUnderstandingRequest baseBuild(String content, Stri...

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/images/resp/ImageCreateResponse.java
  class ImageCreateResponse (line 14) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/endPoint/images/resp/ImageUnderstandingResponse.java
  class ImageUnderstandingResponse (line 14) | @Data

FILE: ai-spark/src/main/java/com/ai/spark/interceptor/BaseUrlInterceptor.java
  class BaseUrlInterceptor (line 11) | @Slf4j
    method intercept (line 14) | @Override

FILE: ai-spark/src/main/java/com/ai/spark/interceptor/ResponseInterceptor.java
  class ResponseInterceptor (line 15) | @Slf4j
    method intercept (line 17) | @Override

FILE: ai-spark/src/test/java/com/ai/spark/AudioApiTest.java
  class AudioApiTest (line 13) | public class AudioApiTest {
    method before (line 17) | @Before

FILE: ai-spark/src/test/java/com/ai/spark/ChatApiTest.java
  class ChatApiTest (line 23) | public class ChatApiTest {
    method before (line 27) | @Before
    method test_chat (line 52) | @Test
    method test_chat_multiple (line 91) | @Test
    method test_document_chat (line 132) | @Test

FILE: ai-spark/src/test/java/com/ai/spark/DocumentApiTest.java
  class DocumentApiTest (line 17) | public class DocumentApiTest {
    method before (line 21) | @Before
    method test_file_upload (line 46) | @Test
    method test_document_summary_start (line 66) | @Test
    method test_document_summary_query (line 77) | @Test

FILE: ai-spark/src/test/java/com/ai/spark/EmbeddingApiTest.java
  class EmbeddingApiTest (line 17) | public class EmbeddingApiTest {
    method before (line 22) | @Before
    method test_embedding (line 47) | @Test

FILE: ai-spark/src/test/java/com/ai/spark/ImageApiTest.java
  class ImageApiTest (line 25) | public class ImageApiTest {
    method before (line 29) | @Before
    method test_image_create (line 54) | @Test
    method test_image_understanding (line 70) | @Test
Condensed preview — 215 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (418K chars).
[
  {
    "path": "README.md",
    "chars": 5972,
    "preview": "## 目录\n\n- [**项目背景**](#项目背景)\n- [**安装**](#安装)\n- [**使用方式**](#使用方式)\n- [**示例**](#示例)\n- [**更新记录**](#更新记录)\n\n## **项目背景**\n\n## Star"
  },
  {
    "path": "ai-baidu/pom.xml",
    "chars": 1450,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/ApiData.java",
    "chars": 360,
    "preview": "package com.ai.baidu.achieve;\n\n\nimport lombok.AllArgsConstructor;\nimport lombok.Builder;\nimport lombok.Data;\nimport lomb"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/Configuration.java",
    "chars": 889,
    "preview": "package com.ai.baidu.achieve;\n\nimport com.ai.baidu.achieve.standard.api.BaiduApiServer;\nimport com.ai.core.config.BaseCo"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/DefaultBaiduSessionFactory.java",
    "chars": 2417,
    "preview": "package com.ai.baidu.achieve.defaults;\n\nimport com.ai.baidu.achieve.Configuration;\nimport com.ai.baidu.achieve.defaults."
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/DefaultAggregationSession.java",
    "chars": 1860,
    "preview": "package com.ai.baidu.achieve.defaults.session;\n\nimport com.ai.baidu.achieve.Configuration;\nimport com.ai.baidu.achieve.s"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/DefaultChatSession.java",
    "chars": 2253,
    "preview": "package com.ai.baidu.achieve.defaults.session;\n\nimport cn.hutool.http.ContentType;\nimport com.ai.baidu.achieve.Configura"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/DefaultEmbeddingSession.java",
    "chars": 1527,
    "preview": "package com.ai.baidu.achieve.defaults.session;\n\nimport com.ai.baidu.achieve.Configuration;\nimport com.ai.baidu.achieve.s"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/DefaultImageSession.java",
    "chars": 921,
    "preview": "package com.ai.baidu.achieve.defaults.session;\n\nimport com.ai.baidu.achieve.Configuration;\nimport com.ai.baidu.achieve.s"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/defaults/session/Session.java",
    "chars": 1019,
    "preview": "package com.ai.baidu.achieve.defaults.session;\n\nimport cn.hutool.core.util.StrUtil;\nimport com.ai.baidu.achieve.ApiData;"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/standard/api/BaiduApiServer.java",
    "chars": 2617,
    "preview": "package com.ai.baidu.achieve.standard.api;\n\nimport com.ai.baidu.endPoint.auth.resp.AuthResponse;\nimport com.ai.baidu.end"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/standard/session/AggregationSession.java",
    "chars": 344,
    "preview": "package com.ai.baidu.achieve.standard.session;\n\n/**\n * @Description: 聚合各大场景的session\n **/\npublic interface AggregationSes"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/standard/session/ChatSession.java",
    "chars": 1116,
    "preview": "package com.ai.baidu.achieve.standard.session;\n\nimport com.ai.baidu.endPoint.chat.req.ChatRequest;\nimport com.ai.baidu.e"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/standard/session/EmbeddingSession.java",
    "chars": 604,
    "preview": "package com.ai.baidu.achieve.standard.session;\n\nimport com.ai.baidu.endPoint.embedding.req.EmbeddingRequest;\nimport com."
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/achieve/standard/session/ImageSession.java",
    "chars": 556,
    "preview": "package com.ai.baidu.achieve.standard.session;\n\nimport com.ai.baidu.endPoint.images.req.ImageRequest;\nimport com.ai.baid"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/common/ApiUrl.java",
    "chars": 270,
    "preview": "package com.ai.baidu.common;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\n\n/**\n * 各接口API路径\n */\n@Getter\n@AllA"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/common/Usage.java",
    "chars": 757,
    "preview": "package com.ai.baidu.common;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml.jackson"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/endPoint/auth/resp/AuthResponse.java",
    "chars": 1150,
    "preview": "package com.ai.baidu.endPoint.auth.resp;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.faste"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/endPoint/chat/Message.java",
    "chars": 874,
    "preview": "package com.ai.baidu.endPoint.chat;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml."
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/endPoint/chat/SearchResult.java",
    "chars": 570,
    "preview": "package com.ai.baidu.endPoint.chat;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml."
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/endPoint/chat/req/ChatRequest.java",
    "chars": 3048,
    "preview": "package com.ai.baidu.endPoint.chat.req;\n\nimport com.ai.baidu.endPoint.chat.Message;\nimport com.fasterxml.jackson.annotat"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/endPoint/chat/resp/ChatResponse.java",
    "chars": 2121,
    "preview": "package com.ai.baidu.endPoint.chat.resp;\n\nimport com.ai.baidu.common.Usage;\nimport com.ai.baidu.endPoint.chat.SearchResu"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/endPoint/embedding/EmbeddingData.java",
    "chars": 721,
    "preview": "package com.ai.baidu.endPoint.embedding;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport com.fasterxml.jacks"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/endPoint/embedding/req/EmbeddingRequest.java",
    "chars": 1020,
    "preview": "package com.ai.baidu.endPoint.embedding.req;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.f"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/endPoint/embedding/resp/EmbeddingResponse.java",
    "chars": 978,
    "preview": "package com.ai.baidu.endPoint.embedding.resp;\n\nimport com.ai.baidu.common.Usage;\nimport com.ai.baidu.endPoint.embedding."
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/endPoint/images/ImageData.java",
    "chars": 669,
    "preview": "package com.ai.baidu.endPoint.images;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxm"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/endPoint/images/req/ImageRequest.java",
    "chars": 3530,
    "preview": "package com.ai.baidu.endPoint.images.req;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fast"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/endPoint/images/resp/ImageResponse.java",
    "chars": 902,
    "preview": "package com.ai.baidu.endPoint.images.resp;\n\nimport com.ai.baidu.common.Usage;\nimport com.ai.baidu.endPoint.images.ImageD"
  },
  {
    "path": "ai-baidu/src/main/java/com/ai/baidu/interceptor/ResponseInterceptor.java",
    "chars": 643,
    "preview": "package com.ai.baidu.interceptor;\n\nimport lombok.extern.slf4j.Slf4j;\nimport okhttp3.Interceptor;\nimport okhttp3.Request;"
  },
  {
    "path": "ai-baidu/src/test/java/com/ai/baidu/ChatApiTest.java",
    "chars": 4630,
    "preview": "package com.ai.baidu;\n\nimport com.ai.baidu.achieve.ApiData;\nimport com.ai.baidu.achieve.Configuration;\nimport com.ai.bai"
  },
  {
    "path": "ai-baidu/src/test/java/com/ai/baidu/EmbeddingApiTest.java",
    "chars": 2353,
    "preview": "package com.ai.baidu;\n\nimport com.ai.baidu.achieve.ApiData;\nimport com.ai.baidu.achieve.Configuration;\nimport com.ai.bai"
  },
  {
    "path": "ai-baidu/src/test/java/com/ai/baidu/ImageApiTest.java",
    "chars": 2375,
    "preview": "package com.ai.baidu;\n\n\nimport com.ai.baidu.achieve.ApiData;\nimport com.ai.baidu.achieve.Configuration;\nimport com.ai.ba"
  },
  {
    "path": "ai-common/pom.xml",
    "chars": 4371,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "ai-common/src/main/java/com/ai/common/utils/Exceptions.java",
    "chars": 397,
    "preview": "package com.ai.common.utils;\n\n/**\n * 异常工具类\n */\npublic class Exceptions {\n\n    public static IllegalArgumentException ill"
  },
  {
    "path": "ai-common/src/main/java/com/ai/common/utils/ImageUtils.java",
    "chars": 2557,
    "preview": "package com.ai.common.utils;\n\nimport javax.imageio.ImageIO;\nimport java.awt.image.BufferedImage;\nimport java.io.ByteArra"
  },
  {
    "path": "ai-common/src/main/java/com/ai/common/utils/JsonUtils.java",
    "chars": 743,
    "preview": "package com.ai.common.utils;\n\n\nimport com.fasterxml.jackson.core.JsonProcessingException;\nimport com.fasterxml.jackson.d"
  },
  {
    "path": "ai-common/src/main/java/com/ai/common/utils/ValidationUtils.java",
    "chars": 1768,
    "preview": "package com.ai.common.utils;\n\nimport java.util.Collection;\n\nimport static com.ai.common.utils.Exceptions.illegalArgument"
  },
  {
    "path": "ai-core/pom.xml",
    "chars": 1040,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "ai-core/src/main/java/com/ai/core/config/BaseConfiguration.java",
    "chars": 645,
    "preview": "package com.ai.core.config;\n\nimport com.ai.core.strategy.KeyStrategy;\nimport lombok.AllArgsConstructor;\nimport lombok.Da"
  },
  {
    "path": "ai-core/src/main/java/com/ai/core/exception/BaseException.java",
    "chars": 666,
    "preview": "package com.ai.core.exception;\n\nimport lombok.Getter;\n\n@Getter\npublic class BaseException extends RuntimeException {\n\n  "
  },
  {
    "path": "ai-core/src/main/java/com/ai/core/exception/Constants.java",
    "chars": 1973,
    "preview": "package com.ai.core.exception;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\n\nimport java.util.HashMap;\nimpor"
  },
  {
    "path": "ai-core/src/main/java/com/ai/core/exception/IError.java",
    "chars": 97,
    "preview": "package com.ai.core.exception;\n\npublic interface IError {\n\n    String msg();\n\n    int code();\n\n}\n"
  },
  {
    "path": "ai-core/src/main/java/com/ai/core/factory/SessionFactory.java",
    "chars": 482,
    "preview": "package com.ai.core.factory;\n\n\nimport okhttp3.OkHttpClient;\n\npublic interface SessionFactory<Session, ApiServer> {\n\n    "
  },
  {
    "path": "ai-core/src/main/java/com/ai/core/strategy/KeyStrategy.java",
    "chars": 127,
    "preview": "package com.ai.core.strategy;\n\n\n/**\n * @Description: API Key 获取策略\n */\npublic interface KeyStrategy<T, R> {\n    R apply(T"
  },
  {
    "path": "ai-core/src/main/java/com/ai/core/strategy/impl/FirstKeyStrategy.java",
    "chars": 265,
    "preview": "package com.ai.core.strategy.impl;\n\nimport com.ai.core.strategy.KeyStrategy;\n\nimport java.util.List;\n\n\npublic class Firs"
  },
  {
    "path": "ai-core/src/main/java/com/ai/core/strategy/impl/RandomKeyStrategy.java",
    "chars": 321,
    "preview": "package com.ai.core.strategy.impl;\n\nimport cn.hutool.core.util.RandomUtil;\nimport com.ai.core.strategy.KeyStrategy;\n\nimp"
  },
  {
    "path": "ai-openai/pom.xml",
    "chars": 1452,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/Product.java",
    "chars": 806,
    "preview": "package com.ai.openai;\n\npublic class Product {\n\n    private String str1;\n    private String str2;\n\n    public Product(Bu"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/Singleton.java",
    "chars": 418,
    "preview": "package com.ai.openai;\n\n\npublic class Singleton {\n\n    private static volatile Singleton instance;\n\n    private Singleto"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/ThreadPrint.java",
    "chars": 1889,
    "preview": "package com.ai.openai;\n\n\nimport java.util.concurrent.locks.Condition;\nimport java.util.concurrent.locks.Lock;\nimport jav"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/Configuration.java",
    "chars": 893,
    "preview": "package com.ai.openai.achieve;\n\nimport com.ai.core.config.BaseConfiguration;\nimport com.ai.openai.achieve.standard.api.O"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/defaults/DefaultOpenAiSessionFactory.java",
    "chars": 2623,
    "preview": "package com.ai.openai.achieve.defaults;\n\n\nimport com.ai.core.factory.SessionFactory;\nimport com.ai.openai.achieve.Config"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultAggregationSession.java",
    "chars": 3709,
    "preview": "package com.ai.openai.achieve.defaults.session;\n\nimport com.ai.openai.achieve.Configuration;\nimport com.ai.openai.achiev"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultAudioSession.java",
    "chars": 4192,
    "preview": "package com.ai.openai.achieve.defaults.session;\n\nimport cn.hutool.core.util.StrUtil;\nimport com.ai.openai.achieve.Config"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultChatSession.java",
    "chars": 7045,
    "preview": "package com.ai.openai.achieve.defaults.session;\n\n\nimport cn.hutool.http.ContentType;\nimport com.ai.common.utils.JsonUtil"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultEmbeddingSession.java",
    "chars": 2373,
    "preview": "package com.ai.openai.achieve.defaults.session;\n\nimport com.ai.openai.achieve.Configuration;\nimport com.ai.openai.achiev"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultFilesSession.java",
    "chars": 2740,
    "preview": "package com.ai.openai.achieve.defaults.session;\n\nimport com.ai.openai.achieve.Configuration;\nimport com.ai.openai.achiev"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultFineTuningSession.java",
    "chars": 3081,
    "preview": "package com.ai.openai.achieve.defaults.session;\n\nimport com.ai.openai.achieve.Configuration;\nimport com.ai.openai.achiev"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultImageSession.java",
    "chars": 4724,
    "preview": "package com.ai.openai.achieve.defaults.session;\n\nimport com.ai.openai.achieve.Configuration;\nimport com.ai.openai.achiev"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultModelSession.java",
    "chars": 1734,
    "preview": "package com.ai.openai.achieve.defaults.session;\n\n\nimport com.ai.openai.achieve.Configuration;\nimport com.ai.openai.achie"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/DefaultModerationSession.java",
    "chars": 1635,
    "preview": "package com.ai.openai.achieve.defaults.session;\n\n\nimport com.ai.openai.achieve.Configuration;\nimport com.ai.openai.achie"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/defaults/session/Session.java",
    "chars": 354,
    "preview": "package com.ai.openai.achieve.defaults.session;\n\nimport com.ai.openai.achieve.Configuration;\nimport com.ai.openai.achiev"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/standard/api/OpenaiApiServer.java",
    "chars": 14428,
    "preview": "package com.ai.openai.achieve.standard.api;\n\nimport com.ai.openai.common.CommonListResponse;\nimport com.ai.openai.endPoi"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/standard/session/AggregationSession.java",
    "chars": 709,
    "preview": "package com.ai.openai.achieve.standard.session;\n\n/**\n * @Description: 聚合各大场景的session\n **/\npublic interface AggregationSe"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/standard/session/AudioSession.java",
    "chars": 1524,
    "preview": "package com.ai.openai.achieve.standard.session;\n\nimport com.ai.openai.endPoint.audio.req.SttCompletionRequest;\nimport co"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/standard/session/ChatSession.java",
    "chars": 3745,
    "preview": "package com.ai.openai.achieve.standard.session;\n\nimport com.ai.openai.endPoint.chat.req.DefaultChatCompletionRequest;\nim"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/standard/session/EmbeddingSession.java",
    "chars": 1390,
    "preview": "package com.ai.openai.achieve.standard.session;\n\nimport com.ai.openai.endPoint.embeddings.req.EmbeddingCompletionRequest"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/standard/session/FilesSession.java",
    "chars": 1936,
    "preview": "package com.ai.openai.achieve.standard.session;\n\nimport com.ai.openai.endPoint.files.FileObject;\nimport com.ai.openai.en"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/standard/session/FineTuningSession.java",
    "chars": 2741,
    "preview": "package com.ai.openai.achieve.standard.session;\n\nimport com.ai.openai.common.CommonListResponse;\nimport com.ai.openai.en"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/standard/session/ImageSession.java",
    "chars": 1718,
    "preview": "package com.ai.openai.achieve.standard.session;\n\nimport com.ai.openai.endPoint.images.ImageObject;\nimport com.ai.openai."
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/standard/session/ModelSession.java",
    "chars": 1208,
    "preview": "package com.ai.openai.achieve.standard.session;\n\n\nimport com.ai.openai.endPoint.models.ModelObject;\nimport com.ai.openai"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/achieve/standard/session/ModerationSession.java",
    "chars": 617,
    "preview": "package com.ai.openai.achieve.standard.session;\n\n\nimport com.ai.openai.endPoint.moderations.req.ModerationRequest;\nimpor"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/common/ApiUrl.java",
    "chars": 811,
    "preview": "package com.ai.openai.common;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\n\n/**\n * 各接口API路径\n */\n@Getter\n@All"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/common/CommonListResponse.java",
    "chars": 775,
    "preview": "package com.ai.openai.common;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml.jackso"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/common/Usage.java",
    "chars": 547,
    "preview": "package com.ai.openai.common;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport lombok.AllArgsConstructor;\ni"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/audio/req/SttCompletionRequest.java",
    "chars": 1407,
    "preview": "package com.ai.openai.endPoint.audio.req;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fast"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/audio/req/TtsCompletionRequest.java",
    "chars": 1835,
    "preview": "package com.ai.openai.endPoint.audio.req;\n\nimport com.ai.openai.endPoint.chat.req.BaseChatCompletionRequest;\nimport com."
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/audio/resp/SttCompletionResponse.java",
    "chars": 531,
    "preview": "package com.ai.openai.endPoint.audio.resp;\n\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fa"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/ChatChoice.java",
    "chars": 910,
    "preview": "package com.ai.openai.endPoint.chat;\n\nimport com.ai.openai.endPoint.chat.msg.DefaultMessage;\nimport com.fasterxml.jackso"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/Parameters.java",
    "chars": 492,
    "preview": "package com.ai.openai.endPoint.chat;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Builder;\nimport lombok.Data;\nimpor"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/QaChoice.java",
    "chars": 555,
    "preview": "package com.ai.openai.endPoint.chat;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport lombok.AllArgsConstru"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/ResponseFormat.java",
    "chars": 454,
    "preview": "package com.ai.openai.endPoint.chat;\n\nimport lombok.*;\n\n/**\n * @Author: jianglinhong\n * @Description: TODO\n * @DateTime:"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/BaseMessage.java",
    "chars": 647,
    "preview": "package com.ai.openai.endPoint.chat.msg;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.faste"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/Content.java",
    "chars": 1118,
    "preview": "package com.ai.openai.endPoint.chat.msg;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\nimport com.fasterxml.jack"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/DefaultMessage.java",
    "chars": 866,
    "preview": "package com.ai.openai.endPoint.chat.msg;\n\nimport com.ai.openai.endPoint.chat.tools.ToolCall;\nimport com.fasterxml.jackso"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/ImageUrl.java",
    "chars": 420,
    "preview": "package com.ai.openai.endPoint.chat.msg;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\nimport lombok.AllArgsCons"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/msg/ImgMessage.java",
    "chars": 1143,
    "preview": "package com.ai.openai.endPoint.chat.msg;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\nimport lombok.AllArgsCons"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/BaseChatCompletionRequest.java",
    "chars": 2207,
    "preview": "package com.ai.openai.endPoint.chat.req;\n\nimport com.ai.openai.endPoint.chat.ResponseFormat;\nimport com.fasterxml.jackso"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/DefaultChatCompletionRequest.java",
    "chars": 1808,
    "preview": "package com.ai.openai.endPoint.chat.req;\n\nimport com.ai.core.exception.Constants;\nimport com.ai.openai.endPoint.chat.msg"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/FuncChatCompletionRequest.java",
    "chars": 2001,
    "preview": "package com.ai.openai.endPoint.chat.req;\n\nimport com.ai.core.exception.Constants;\nimport com.ai.openai.endPoint.chat.msg"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/ImgChatCompletionRequest.java",
    "chars": 779,
    "preview": "package com.ai.openai.endPoint.chat.req;\n\nimport com.ai.openai.endPoint.chat.msg.ImgMessage;\nimport com.fasterxml.jackso"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/req/QaCompletionRequest.java",
    "chars": 2520,
    "preview": "package com.ai.openai.endPoint.chat.req;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.faste"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/resp/ChatCompletionResponse.java",
    "chars": 1213,
    "preview": "package com.ai.openai.endPoint.chat.resp;\n\nimport com.ai.openai.common.Usage;\nimport com.ai.openai.endPoint.chat.ChatCho"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/resp/QaCompletionResponse.java",
    "chars": 1015,
    "preview": "package com.ai.openai.endPoint.chat.resp;\n\n\nimport com.ai.openai.common.Usage;\nimport com.ai.openai.endPoint.chat.QaChoi"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/tools/Tool.java",
    "chars": 457,
    "preview": "package com.ai.openai.endPoint.chat.tools;\n\nimport lombok.*;\n\nimport java.io.Serializable;\n\n@Data\n@Builder\n@AllArgsConst"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/tools/ToolCall.java",
    "chars": 466,
    "preview": "package com.ai.openai.endPoint.chat.tools;\n\nimport lombok.*;\n\nimport java.io.Serializable;\n\n/**\n * @Description: 函数式对话返回"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/tools/ToolCallFunction.java",
    "chars": 438,
    "preview": "package com.ai.openai.endPoint.chat.tools;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Builder;\nimport lombok.Data;"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/chat/tools/ToolFunction.java",
    "chars": 608,
    "preview": "package com.ai.openai.endPoint.chat.tools;\n\nimport com.ai.openai.endPoint.chat.Parameters;\nimport lombok.AllArgsConstruc"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/embeddings/EmbeddingObject.java",
    "chars": 596,
    "preview": "package com.ai.openai.endPoint.embeddings;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport lombok.AllArgsCon"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/embeddings/req/EmbeddingCompletionRequest.java",
    "chars": 1585,
    "preview": "package com.ai.openai.endPoint.embeddings.req;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/embeddings/resp/EmbeddingCompletionResponse.java",
    "chars": 1179,
    "preview": "package com.ai.openai.endPoint.embeddings.resp;\n\nimport com.ai.openai.common.Usage;\nimport com.ai.openai.endPoint.embedd"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/files/FileObject.java",
    "chars": 940,
    "preview": "package com.ai.openai.endPoint.files;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport lombok.AllArgsConstr"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/files/resp/DeleteFileResponse.java",
    "chars": 579,
    "preview": "package com.ai.openai.endPoint.files.resp;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fas"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/FineTuneError.java",
    "chars": 482,
    "preview": "package com.ai.openai.endPoint.fineTuning;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.NoArgsCo"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/FineTuningEvent.java",
    "chars": 555,
    "preview": "package com.ai.openai.endPoint.fineTuning;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport lombok.AllArgsC"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/HyperParameters.java",
    "chars": 869,
    "preview": "package com.ai.openai.endPoint.fineTuning;\n\nimport com.fasterxml.jackson.annotation.JsonInclude;\nimport com.fasterxml.ja"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/req/FineTuningRequest.java",
    "chars": 1366,
    "preview": "package com.ai.openai.endPoint.fineTuning.req;\n\nimport com.ai.openai.endPoint.fineTuning.HyperParameters;\nimport com.fas"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/req/ListFineTuningRequest.java",
    "chars": 639,
    "preview": "package com.ai.openai.endPoint.fineTuning.req;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/fineTuning/resp/FineTuningResponse.java",
    "chars": 1980,
    "preview": "package com.ai.openai.endPoint.fineTuning.resp;\n\nimport com.ai.openai.endPoint.fineTuning.HyperParameters;\nimport com.fa"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/images/ImageObject.java",
    "chars": 411,
    "preview": "package com.ai.openai.endPoint.images;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport lombok.AllArgsConst"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/images/req/CreateImageRequest.java",
    "chars": 2407,
    "preview": "package com.ai.openai.endPoint.images.req;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fas"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/images/req/ImageEditRequest.java",
    "chars": 1616,
    "preview": "package com.ai.openai.endPoint.images.req;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fas"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/images/req/ImageVariationRequest.java",
    "chars": 1361,
    "preview": "package com.ai.openai.endPoint.images.req;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fas"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/images/resp/CreateImageResponse.java",
    "chars": 553,
    "preview": "package com.ai.openai.endPoint.images.resp;\n\nimport com.ai.openai.endPoint.images.ImageObject;\nimport com.fasterxml.jack"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/models/ModelObject.java",
    "chars": 558,
    "preview": "package com.ai.openai.endPoint.models;\n\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport lombok.AllArgsCons"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/models/resp/DeleteFineTuneModelResponse.java",
    "chars": 560,
    "preview": "package com.ai.openai.endPoint.models.resp;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fa"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/moderations/Categories.java",
    "chars": 1600,
    "preview": "package com.ai.openai.endPoint.moderations;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport lombok.AllArgs"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/moderations/CategoryScores.java",
    "chars": 1291,
    "preview": "package com.ai.openai.endPoint.moderations;\n\nimport com.fasterxml.jackson.annotation.JsonProperty;\nimport lombok.AllArgs"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/moderations/Result.java",
    "chars": 702,
    "preview": "package com.ai.openai.endPoint.moderations;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport com.fasterxml.ja"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/moderations/req/ModerationRequest.java",
    "chars": 1271,
    "preview": "package com.ai.openai.endPoint.moderations.req;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport co"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/endPoint/moderations/resp/ModerationResponse.java",
    "chars": 680,
    "preview": "package com.ai.openai.endPoint.moderations.resp;\n\nimport com.ai.openai.endPoint.moderations.Result;\nimport com.fasterxml"
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/interceptor/HeaderInterceptor.java",
    "chars": 2109,
    "preview": "package com.ai.openai.interceptor;\n\nimport cn.hutool.http.ContentType;\nimport cn.hutool.http.Header;\nimport com.ai.core."
  },
  {
    "path": "ai-openai/src/main/java/com/ai/openai/interceptor/ResponseInterceptor.java",
    "chars": 1533,
    "preview": "package com.ai.openai.interceptor;\n\nimport cn.hutool.json.JSONUtil;\nimport com.ai.core.exception.BaseException;\nimport c"
  },
  {
    "path": "ai-openai/src/test/java/com/ai/openai/AudioApiTest.java",
    "chars": 4735,
    "preview": "package com.ai.openai;\n\nimport com.ai.core.strategy.impl.FirstKeyStrategy;\nimport com.ai.openai.achieve.Configuration;\ni"
  },
  {
    "path": "ai-openai/src/test/java/com/ai/openai/ChatApiTest.java",
    "chars": 9724,
    "preview": "package com.ai.openai;\n\nimport cn.hutool.json.JSONObject;\nimport com.ai.core.exception.Constants;\nimport com.ai.core.str"
  },
  {
    "path": "ai-openai/src/test/java/com/ai/openai/EmbeddingApiTest.java",
    "chars": 3229,
    "preview": "package com.ai.openai;\n\nimport com.ai.core.strategy.impl.FirstKeyStrategy;\nimport com.ai.openai.achieve.Configuration;\ni"
  },
  {
    "path": "ai-openai/src/test/java/com/ai/openai/FilesApiTest.java",
    "chars": 3089,
    "preview": "package com.ai.openai;\n\nimport com.ai.core.strategy.impl.FirstKeyStrategy;\nimport com.ai.openai.achieve.Configuration;\ni"
  },
  {
    "path": "ai-openai/src/test/java/com/ai/openai/FineTuningApiTest.java",
    "chars": 4059,
    "preview": "package com.ai.openai;\n\nimport com.ai.core.strategy.impl.FirstKeyStrategy;\nimport com.ai.openai.achieve.Configuration;\ni"
  },
  {
    "path": "ai-openai/src/test/java/com/ai/openai/ImageApiTest.java",
    "chars": 3969,
    "preview": "package com.ai.openai;\n\nimport com.ai.common.utils.ImageUtils;\nimport com.ai.core.strategy.impl.FirstKeyStrategy;\nimport"
  },
  {
    "path": "ai-openai/src/test/java/com/ai/openai/ModelApiTest.java",
    "chars": 2488,
    "preview": "package com.ai.openai;\n\nimport com.ai.core.strategy.impl.FirstKeyStrategy;\nimport com.ai.openai.achieve.Configuration;\ni"
  },
  {
    "path": "ai-openai/src/test/java/com/ai/openai/ModerationApiTest.java",
    "chars": 2303,
    "preview": "package com.ai.openai;\n\nimport com.ai.core.strategy.impl.FirstKeyStrategy;\nimport com.ai.openai.achieve.Configuration;\ni"
  },
  {
    "path": "ai-spark/pom.xml",
    "chars": 1450,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/ApiData.java",
    "chars": 328,
    "preview": "package com.ai.spark.achieve;\n\n\nimport lombok.AllArgsConstructor;\nimport lombok.Builder;\nimport lombok.Data;\nimport lomb"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/Configuration.java",
    "chars": 686,
    "preview": "package com.ai.spark.achieve;\n\nimport com.ai.core.config.BaseConfiguration;\nimport com.ai.spark.achieve.standard.api.Spa"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/defaults/DefaultSparkSessionFactory.java",
    "chars": 2653,
    "preview": "package com.ai.spark.achieve.defaults;\n\nimport com.ai.core.factory.SessionFactory;\nimport com.ai.spark.achieve.Configura"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/defaults/listener/BaseListener.java",
    "chars": 1914,
    "preview": "package com.ai.spark.achieve.defaults.listener;\n\nimport lombok.Data;\nimport lombok.extern.slf4j.Slf4j;\nimport okhttp3.Re"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/defaults/listener/ChatListener.java",
    "chars": 3255,
    "preview": "package com.ai.spark.achieve.defaults.listener;\n\nimport com.ai.common.utils.JsonUtils;\nimport com.ai.spark.common.Usage;"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/defaults/listener/DocumentChatListener.java",
    "chars": 3348,
    "preview": "package com.ai.spark.achieve.defaults.listener;\n\nimport com.ai.common.utils.JsonUtils;\nimport com.ai.spark.endPoint.chat"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/defaults/listener/ImageUnderstandingListener.java",
    "chars": 3731,
    "preview": "package com.ai.spark.achieve.defaults.listener;\n\nimport com.ai.common.utils.JsonUtils;\nimport com.ai.spark.endPoint.chat"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/DefaultAggregationSession.java",
    "chars": 2423,
    "preview": "package com.ai.spark.achieve.defaults.session;\n\nimport com.ai.spark.achieve.Configuration;\nimport com.ai.spark.achieve.s"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/DefaultAudioSession.java",
    "chars": 689,
    "preview": "package com.ai.spark.achieve.defaults.session;\n\nimport com.ai.spark.achieve.Configuration;\nimport com.ai.spark.achieve.s"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/DefaultChatSession.java",
    "chars": 2922,
    "preview": "package com.ai.spark.achieve.defaults.session;\n\n\nimport cn.hutool.core.date.DateUtil;\nimport com.ai.spark.achieve.ApiDat"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/DefaultDocumentSession.java",
    "chars": 4747,
    "preview": "package com.ai.spark.achieve.defaults.session;\n\nimport cn.hutool.core.date.DateUtil;\nimport cn.hutool.core.util.StrUtil;"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/DefaultEmbeddingSession.java",
    "chars": 2138,
    "preview": "package com.ai.spark.achieve.defaults.session;\n\nimport cn.hutool.http.ContentType;\nimport com.ai.common.utils.JsonUtils;"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/DefaultImageSession.java",
    "chars": 3399,
    "preview": "package com.ai.spark.achieve.defaults.session;\n\nimport cn.hutool.http.ContentType;\nimport com.ai.common.utils.JsonUtils;"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/defaults/session/Session.java",
    "chars": 287,
    "preview": "package com.ai.spark.achieve.defaults.session;\n\nimport com.ai.spark.achieve.Configuration;\nimport com.ai.spark.achieve.s"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/standard/api/SparkApiServer.java",
    "chars": 1492,
    "preview": "package com.ai.spark.achieve.standard.api;\n\n\nimport com.ai.spark.endPoint.document.resp.DocumentSummaryResponse;\nimport "
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/standard/session/AggregationSession.java",
    "chars": 287,
    "preview": "package com.ai.spark.achieve.standard.session;\n\n\npublic interface AggregationSession {\n\n    ChatSession getChatSession()"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/standard/session/AudioSession.java",
    "chars": 84,
    "preview": "package com.ai.spark.achieve.standard.session;\n\n\npublic interface AudioSession {\n\n}\n"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/standard/session/ChatSession.java",
    "chars": 1209,
    "preview": "package com.ai.spark.achieve.standard.session;\n\n\nimport com.ai.spark.achieve.defaults.listener.ChatListener;\nimport com."
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/standard/session/DocumentSession.java",
    "chars": 1564,
    "preview": "package com.ai.spark.achieve.standard.session;\n\n\nimport com.ai.spark.endPoint.document.req.FileUploadRequest;\nimport com"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/standard/session/EmbeddingSession.java",
    "chars": 665,
    "preview": "package com.ai.spark.achieve.standard.session;\n\n\nimport com.ai.spark.endPoint.embedding.req.EmbeddingRequest;\nimport com"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/achieve/standard/session/ImageSession.java",
    "chars": 1605,
    "preview": "package com.ai.spark.achieve.standard.session;\n\n\nimport com.ai.spark.achieve.defaults.listener.ImageUnderstandingListene"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/common/Constants.java",
    "chars": 221,
    "preview": "package com.ai.spark.common;\n\n\npublic class Constants {\n\n    public static final String APP_ID = \"appId\";\n    public sta"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/common/SparkApiUrl.java",
    "chars": 4524,
    "preview": "package com.ai.spark.common;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\nimport lombok.extern.slf4j.Slf4j;\n"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/common/Usage.java",
    "chars": 503,
    "preview": "package com.ai.spark.common;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml.jackson"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/common/UsageText.java",
    "chars": 901,
    "preview": "package com.ai.spark.common;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml.jackson"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/common/utils/AuthUtils.java",
    "chars": 5072,
    "preview": "package com.ai.spark.common.utils;\n\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\n\nimport javax.crypto.Mac;\ni"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/audio/Audio.java",
    "chars": 1119,
    "preview": "package com.ai.spark.endPoint.audio;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/audio/AudioHeader.java",
    "chars": 1635,
    "preview": "package com.ai.spark.endPoint.audio;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/audio/AudioParameter.java",
    "chars": 484,
    "preview": "package com.ai.spark.endPoint.audio;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/audio/AudioPayload.java",
    "chars": 771,
    "preview": "package com.ai.spark.endPoint.audio;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/audio/AudioText.java",
    "chars": 772,
    "preview": "package com.ai.spark.endPoint.audio;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/audio/Oral.java",
    "chars": 613,
    "preview": "package com.ai.spark.endPoint.audio;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/audio/Pybuf.java",
    "chars": 847,
    "preview": "package com.ai.spark.endPoint.audio;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/audio/Tts.java",
    "chars": 1823,
    "preview": "package com.ai.spark.endPoint.audio;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/audio/req/AudioRequest.java",
    "chars": 1191,
    "preview": "package com.ai.spark.endPoint.audio.req;\n\nimport com.ai.spark.endPoint.audio.AudioHeader;\nimport com.ai.spark.endPoint.a"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/audio/resp/AudioResponse.java",
    "chars": 607,
    "preview": "package com.ai.spark.endPoint.audio.resp;\n\nimport com.ai.spark.endPoint.audio.AudioHeader;\nimport com.ai.spark.endPoint."
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/Chat.java",
    "chars": 1335,
    "preview": "package com.ai.spark.endPoint.chat;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml."
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/ChatHeader.java",
    "chars": 1050,
    "preview": "package com.ai.spark.endPoint.chat;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml."
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/ChatParameter.java",
    "chars": 460,
    "preview": "package com.ai.spark.endPoint.chat;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml."
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/ChatPayload.java",
    "chars": 771,
    "preview": "package com.ai.spark.endPoint.chat;\n\nimport com.ai.spark.common.Usage;\nimport com.ai.spark.endPoint.chat.function.Functi"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/ChatText.java",
    "chars": 1243,
    "preview": "package com.ai.spark.endPoint.chat;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml."
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/Choice.java",
    "chars": 860,
    "preview": "package com.ai.spark.endPoint.chat;\n\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/Message.java",
    "chars": 573,
    "preview": "package com.ai.spark.endPoint.chat;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxml."
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/document/ChatExtends.java",
    "chars": 1013,
    "preview": "package com.ai.spark.endPoint.chat.document;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.f"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/function/Function.java",
    "chars": 564,
    "preview": "package com.ai.spark.endPoint.chat.function;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.f"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/function/FunctionParameter.java",
    "chars": 655,
    "preview": "package com.ai.spark.endPoint.chat.function;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.f"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/function/FunctionText.java",
    "chars": 705,
    "preview": "package com.ai.spark.endPoint.chat.function;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.f"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/req/ChatRequest.java",
    "chars": 1529,
    "preview": "package com.ai.spark.endPoint.chat.req;\n\nimport com.ai.spark.endPoint.chat.*;\nimport com.fasterxml.jackson.annotation.Js"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/req/DocumentChatRequest.java",
    "chars": 1224,
    "preview": "package com.ai.spark.endPoint.chat.req;\n\nimport com.ai.spark.endPoint.chat.ChatText;\nimport com.ai.spark.endPoint.chat.d"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/resp/ChatResponse.java",
    "chars": 716,
    "preview": "package com.ai.spark.endPoint.chat.resp;\n\nimport com.ai.spark.endPoint.chat.ChatHeader;\nimport com.ai.spark.endPoint.cha"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/chat/resp/DocumentChatResponse.java",
    "chars": 1135,
    "preview": "package com.ai.spark.endPoint.chat.resp;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.faste"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/document/Data.java",
    "chars": 480,
    "preview": "package com.ai.spark.endPoint.document;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.faster"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/document/req/FileUploadRequest.java",
    "chars": 1026,
    "preview": "package com.ai.spark.endPoint.document.req;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fa"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/document/resp/DocumentSummaryResponse.java",
    "chars": 582,
    "preview": "package com.ai.spark.endPoint.document.resp;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.f"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/document/resp/FileUploadResponse.java",
    "chars": 708,
    "preview": "package com.ai.spark.endPoint.document.resp;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.f"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/embedding/Emb.java",
    "chars": 526,
    "preview": "package com.ai.spark.endPoint.embedding;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.faste"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/embedding/EmbeddingHeader.java",
    "chars": 1079,
    "preview": "package com.ai.spark.endPoint.embedding;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.faste"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/embedding/EmbeddingMessage.java",
    "chars": 535,
    "preview": "package com.ai.spark.endPoint.embedding;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.faste"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/embedding/EmbeddingParameter.java",
    "chars": 613,
    "preview": "package com.ai.spark.endPoint.embedding;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.faste"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/embedding/EmbeddingPayload.java",
    "chars": 671,
    "preview": "package com.ai.spark.endPoint.embedding;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.faste"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/embedding/Feature.java",
    "chars": 636,
    "preview": "package com.ai.spark.endPoint.embedding;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.faste"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/embedding/req/EmbeddingRequest.java",
    "chars": 1801,
    "preview": "package com.ai.spark.endPoint.embedding.req;\n\nimport com.ai.common.utils.JsonUtils;\nimport com.ai.spark.endPoint.chat.Ch"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/embedding/resp/EmbeddingResponse.java",
    "chars": 834,
    "preview": "package com.ai.spark.endPoint.embedding.resp;\n\nimport com.ai.spark.endPoint.embedding.EmbeddingHeader;\nimport com.ai.spa"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/images/ImageChat.java",
    "chars": 673,
    "preview": "package com.ai.spark.endPoint.images;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxm"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/images/ImageHeader.java",
    "chars": 767,
    "preview": "package com.ai.spark.endPoint.images;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxm"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/images/ImageParameter.java",
    "chars": 672,
    "preview": "package com.ai.spark.endPoint.images;\n\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterx"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/images/ImagePayload.java",
    "chars": 730,
    "preview": "package com.ai.spark.endPoint.images;\n\nimport com.ai.spark.endPoint.chat.Choice;\nimport com.ai.spark.endPoint.chat.Messa"
  },
  {
    "path": "ai-spark/src/main/java/com/ai/spark/endPoint/images/ImageUnderstandingChat.java",
    "chars": 810,
    "preview": "package com.ai.spark.endPoint.images;\n\nimport com.fasterxml.jackson.annotation.JsonIgnoreProperties;\nimport com.fasterxm"
  }
]

// ... and 15 more files (download for full content)

About this extraction

This page contains the full source code of the mainpropath/AI-java GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 215 files (334.8 KB), approximately 96.4k tokens, and a symbol index with 644 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!