Browse Source

新增moonshot-AI代码

zjc 9 months ago
parent
commit
a9238d984e
17 changed files with 890 additions and 0 deletions
  1. 65 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/moonshot/MoonshotFileController.java
  2. 4 0
      ruoyi-admin/src/main/resources/application.yml
  3. 22 0
      ruoyi-common/pom.xml
  4. 9 0
      ruoyi-common/src/main/java/com/ruoyi/common/enums/ChatMessageRole.java
  5. 235 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/Client.java
  6. 93 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/MoonshotDemoMain.java
  7. 36 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionChoice.java
  8. 32 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionMessage.java
  9. 42 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionRequest.java
  10. 37 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionResponse.java
  11. 51 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionStreamChoice.java
  12. 27 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionStreamChoiceDelta.java
  13. 43 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionStreamResponse.java
  14. 94 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/FileUploadResult.java
  15. 61 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/Model.java
  16. 20 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ModelsList.java
  17. 19 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/Usage.java

+ 65 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/moonshot/MoonshotFileController.java

@@ -0,0 +1,65 @@
+package com.ruoyi.web.controller.moonshot;
+
+
+import com.ruoyi.common.config.RuoYiConfig;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.utils.file.FileUploadUtils;
+import com.ruoyi.common.utils.file.FileUtils;
+import com.ruoyi.common.utils.moonshot.Client;
+import com.ruoyi.common.utils.moonshot.vo.FileUploadResult;
+import com.ruoyi.framework.config.ServerConfig;
+import com.ruoyi.web.controller.common.CommonController;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+
+@RestController
+@RequestMapping("/moonshot/file")
+public class MoonshotFileController {
+
+    private static final Logger log = LoggerFactory.getLogger(CommonController.class);
+
+    @Autowired
+    private ServerConfig serverConfig;
+
+    @Value("${moonshot.api_key}")
+    private String API_KEY;
+
+    /**
+     * 通用上传请求(单个)
+     */
+    @PostMapping("/upload")
+    public AjaxResult uploadFile(MultipartFile file) throws Exception
+    {
+        AjaxResult ajax = AjaxResult.success();
+        try
+        {
+            if (API_KEY == null) {
+                System.out.println("Please set MOONSHOT_API_KEY env");
+                ajax.put("API_KEY","接口API_KEY不存在");
+                return ajax;
+            }
+            Client client = new Client(API_KEY);
+
+            FileUploadResult resuat = client.uploadFile(file);
+
+
+
+            ajax.put("FileUploadResult", resuat);
+            return ajax;
+        }
+        catch (Exception e)
+        {
+            return AjaxResult.error(e.getMessage());
+        }
+    }
+
+
+}

+ 4 - 0
ruoyi-admin/src/main/resources/application.yml

@@ -148,3 +148,7 @@ dingtalk:
   # 企业ID
   corp_id: ding4ab75ecd53106cde4ac5d6980864d335
 
+# moonshot
+moonshot:
+  # 月之暗面接口标识API_KEY
+  api_key: sk-6RRz9mTfCnit49IQwpxs3oa2JHqfOVuQvWDy3HauX2CExvwg

+ 22 - 0
ruoyi-common/pom.xml

@@ -146,6 +146,28 @@
             <version>2.0.0</version>
         </dependency>
 
+        <!-- Kimi AI  -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.24</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.25</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.moonshot.platform</groupId>
+            <artifactId>moonshot-ai-java-sdk</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>io.reactivex.rxjava2</groupId>
+            <artifactId>rxjava</artifactId>
+            <version>2.2.21</version>
+        </dependency>
+
         <!-- okhttp3 -->
         <dependency>
             <groupId>com.squareup.okhttp3</groupId>

+ 9 - 0
ruoyi-common/src/main/java/com/ruoyi/common/enums/ChatMessageRole.java

@@ -0,0 +1,9 @@
+package com.ruoyi.common.enums;
+
+public enum ChatMessageRole {
+    SYSTEM, USER, ASSISTANT;
+
+    public String value() {
+        return this.name().toLowerCase();
+    }
+}

+ 235 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/Client.java

@@ -0,0 +1,235 @@
+package com.ruoyi.common.utils.moonshot;
+
+import com.ruoyi.common.utils.moonshot.vo.*;
+import com.google.gson.Gson;
+import io.reactivex.BackpressureStrategy;
+import io.reactivex.Flowable;
+import okhttp3.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+public class Client {
+
+
+    private static final String DEFAULT_BASE_URL = "https://api.moonshot.cn/v1";
+
+    private static final String CHAT_COMPLETION_SUFFIX = "/chat/completions";
+    private static final String MODELS_SUFFIX = "/models";
+    private static final String FILES_SUFFIX = "/files";
+
+    private String baseUrl;
+
+    private String apiKey;
+
+    public Client(String apiKey) {
+        this(apiKey, DEFAULT_BASE_URL);
+    }
+
+    public Client(String apiKey, String baseUrl) {
+        this.apiKey = apiKey;
+        if (baseUrl.endsWith("/")) {
+            baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
+        }
+        this.baseUrl = baseUrl;
+    }
+
+    public String getChatCompletionUrl() {
+        return baseUrl + CHAT_COMPLETION_SUFFIX;
+    }
+
+    public String getModelsUrl() {
+        return baseUrl + MODELS_SUFFIX;
+    }
+
+    public String getFilesUrl() {
+        return baseUrl + FILES_SUFFIX;
+    }
+
+    public String getApiKey() {
+        return apiKey;
+    }
+
+    /**
+     *
+     * @return
+     * @throws IOException
+     */
+    public ModelsList ListModels() throws IOException {
+        OkHttpClient client = new OkHttpClient();
+        Request request = new Request.Builder()
+                .url(getModelsUrl())
+                .addHeader("Authorization", "Bearer " + getApiKey())
+                .build();
+        try {
+            Response response = client.newCall(request).execute();
+            String body = response.body().string();
+            Gson gson = new Gson();
+            return gson.fromJson(body, ModelsList.class);
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+    public String uploadFiles(File file) throws IOException {
+        OkHttpClient client = new OkHttpClient();
+
+        // 假设你有一个文件对象 "file" 需要上传
+        // 这里还需要知道文件的MIME类型,这里以"application/octet-stream"为例,表示任意二进制数据
+        MediaType MEDIA_TYPE_OCTET_STREAM = MediaType.parse("application/octet-stream");
+
+        // 创建一个RequestBody来包装你的文件
+        RequestBody fileBody = RequestBody.create(MEDIA_TYPE_OCTET_STREAM, file);
+
+        // 使用MultipartBody.Builder来构建请求体
+        MultipartBody.Builder multipartBuilder = new MultipartBody.Builder()
+                .setType(MultipartBody.FORM)
+                .addFormDataPart("file", file.getName(), fileBody); // "file" 是表单的键,通常与服务端约定
+
+        // 如果还有其他表单字段,可以这样添加
+        // .addFormDataPart("key", "value");
+
+        MultipartBody multipartBody = multipartBuilder.build();
+
+        // 使用multipartBody作为POST请求的请求体
+        Request request = new Request.Builder()
+                .url(getFilesUrl())
+                .addHeader("Authorization", "Bearer " + getApiKey())
+                .post(multipartBody)
+                .build();
+
+        try {
+            Response response = client.newCall(request).execute();
+            if (!response.isSuccessful()) {
+                throw new IOException("Unexpected code " + response);
+            }
+            // 假设服务器返回的是JSON格式的响应
+            return response.body().string();
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+    public ChatCompletionResponse ChatCompletion(ChatCompletionRequest request) throws IOException {
+        request.stream = false;
+        OkHttpClient client = new OkHttpClient();
+        MediaType mediaType = MediaType.parse("application/json");
+        RequestBody body = RequestBody.create(mediaType, new Gson().toJson(request));
+        Request httpRequest = new Request.Builder()
+                .url(getChatCompletionUrl())
+                .addHeader("Authorization", "Bearer " + getApiKey())
+                .addHeader("Content-Type", "application/json")
+                .post(body)
+                .build();
+        try {
+            Response response = client.newCall(httpRequest).execute();
+            String responseBody = response.body().string();
+            Gson gson = new Gson();
+            return gson.fromJson(responseBody, ChatCompletionResponse.class);
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+    // return a stream of ChatCompletionStreamResponse
+    public Flowable<ChatCompletionStreamResponse> ChatCompletionStream(ChatCompletionRequest request) throws IOException {
+        request.stream = true;
+        OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(30000, TimeUnit.SECONDS)
+                .build();
+        MediaType mediaType = MediaType.parse("application/json");
+        RequestBody body = RequestBody.create(mediaType, new Gson().toJson(request));
+        Request httpRequest = new Request.Builder()
+                .url(getChatCompletionUrl())
+                .addHeader("Authorization", "Bearer " + getApiKey())
+                .addHeader("Content-Type", "application/json")
+                .post(body)
+                .build();
+        Response response = client.newCall(httpRequest).execute();
+        if (response.code() != 200) {
+            throw new RuntimeException("Failed to start stream: " + response.body().string());
+        }
+
+        // get response body line by line
+        return Flowable.create(emitter -> {
+            ResponseBody responseBody = response.body();
+            if (responseBody == null) {
+                emitter.onError(new RuntimeException("Response body is null"));
+                return;
+            }
+            String line;
+            while ((line = responseBody.source().readUtf8Line()) != null) {
+                if (line.startsWith("data:")) {
+                    line = line.substring(5);
+                    line = line.trim();
+                }
+                if (Objects.equals(line, "[DONE]")) {
+                    emitter.onComplete();
+                    return;
+                }
+                line = line.trim();
+                if (line.isEmpty()) {
+                    continue;
+                }
+                Gson gson = new Gson();
+                ChatCompletionStreamResponse streamResponse = gson.fromJson(line, ChatCompletionStreamResponse.class);
+                emitter.onNext(streamResponse);
+            }
+            emitter.onComplete();
+        }, BackpressureStrategy.BUFFER);
+    }
+
+    public FileUploadResult uploadFile(File file) throws IOException {
+
+        OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(30000, TimeUnit.SECONDS)
+                .build();
+        RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
+                .addFormDataPart("file",file.getPath(),
+                        RequestBody.create(MediaType.parse("application/octet-stream"),
+                                file))
+                .addFormDataPart("purpose", "file-extract")
+                .build();
+        Request request = new Request.Builder()
+                .url(getFilesUrl())
+                .method("POST", body)
+                .addHeader("Authorization", "Bearer " + getApiKey())
+                .build();
+        Response response = client.newCall(request).execute();
+        String responseBody = response.body().string();
+        Gson gson = new Gson();
+        return gson.fromJson(responseBody, FileUploadResult.class);
+
+    }
+
+    public FileUploadResult uploadFile(MultipartFile file) throws IOException {
+
+        OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(30000, TimeUnit.SECONDS)
+                .build();
+        RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
+                .addFormDataPart("file",file.getOriginalFilename(),
+                        RequestBody.create(MediaType.parse("application/octet-stream"),
+                                file.getBytes()))
+                .addFormDataPart("purpose", "file-extract")
+                .build();
+        Request request = new Request.Builder()
+                .url(getFilesUrl())
+                .method("POST", body)
+                .addHeader("Authorization", "Bearer " + getApiKey())
+                .build();
+        Response response = client.newCall(request).execute();
+        String responseBody = response.body().string();
+        Gson gson = new Gson();
+        return gson.fromJson(responseBody, FileUploadResult.class);
+
+    }
+
+
+
+}

+ 93 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/MoonshotDemoMain.java

@@ -0,0 +1,93 @@
+package com.ruoyi.common.utils.moonshot;
+
+import cn.moonshot.platform.util.MoonshotAiUtils;
+
+import com.ruoyi.common.enums.ChatMessageRole;
+import com.ruoyi.common.utils.moonshot.vo.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+public class MoonshotDemoMain {
+
+    public static void main(String... args) throws IOException {
+
+        String apiKey = "sk-6RRz9mTfCnit49IQwpxs3oa2JHqfOVuQvWDy3HauX2CExvwg";
+        if (apiKey == null) {
+            System.out.println("Please set MOONSHOT_API_KEY env");
+            return;
+        }
+        Client client = new Client(apiKey);
+
+        File file = new File("/D:/szty/695b2905-dda7-4e7d-b321-641ea3b06c74.pdf");
+        FileUploadResult resuat = client.uploadFile(file);
+
+        if(resuat.getStatus().equals("ok")) {
+            String fileId = resuat.getId();
+
+            String fileContent = MoonshotAiUtils.getFileContent(fileId,client.getApiKey());
+            System.out.println(fileContent);
+            final List<ChatCompletionMessage> messages = Arrays.asList(
+                    new ChatCompletionMessage(ChatMessageRole.SYSTEM.value(),
+                            "你是计算机行业专业面试官,提供一套面试题,并根据回复的答案进行分析和人员的能力程度"),
+                    new ChatCompletionMessage(ChatMessageRole.SYSTEM.value(),
+                            fileContent),
+                    new ChatCompletionMessage(ChatMessageRole.SYSTEM.value(),
+                            ""),
+                    new ChatCompletionMessage(ChatMessageRole.USER.value(),
+                            "请描述一下回答情况,水平")
+            );
+
+//        try {
+//            ChatCompletionResponse response = client.ChatCompletion(new ChatCompletionRequest(
+//                    "moonshot-v1-8k",
+//                    messages,
+//                    50,
+//                    0.3f,
+//                    1
+//            ));
+//            for (ChatCompletionChoice choice : response.getChoices()) {
+//                System.out.println(choice.getMessage().getContent());
+//            }
+//        } catch (IOException e) {
+//            e.printStackTrace();
+//        }
+
+            try {
+                client.ChatCompletionStream(new ChatCompletionRequest(
+                        "moonshot-v1-32k",
+                        messages,
+                        1024,
+                        0.3f,
+                        1
+                )).subscribe(
+                        streamResponse -> {
+                            if (streamResponse.getChoices().isEmpty()) {
+                                return;
+                            }
+                            for (ChatCompletionStreamChoice choice : streamResponse.getChoices()) {
+                                String finishReason = choice.getFinishReason();
+                                if (finishReason != null) {
+                                    System.out.print("finish reason: " + finishReason);
+                                    continue;
+                                }
+                                System.out.print(choice.getDelta().getContent());
+                            }
+                        },
+                        error -> {
+                            error.printStackTrace();
+                        },
+                        () -> {
+                            System.out.println("complete");
+                        }
+                );
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+}

+ 36 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionChoice.java

@@ -0,0 +1,36 @@
+package com.ruoyi.common.utils.moonshot.vo;
+
+import com.google.gson.annotations.SerializedName;
+
+public class ChatCompletionChoice {
+    private int index;
+    private ChatCompletionMessage message;
+
+    @SerializedName("finish_reason")
+    private String finishReason;
+
+    public int getIndex() {
+        return index;
+    }
+
+    public ChatCompletionMessage getMessage() {
+        return message;
+    }
+
+    public String getFinishReason() {
+        return finishReason;
+    }
+
+    public void setIndex(int index) {
+        this.index = index;
+    }
+
+    public void setMessage(ChatCompletionMessage message) {
+        this.message = message;
+    }
+
+    public void setFinishReason(String finishReason) {
+        this.finishReason = finishReason;
+    }
+
+}

+ 32 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionMessage.java

@@ -0,0 +1,32 @@
+package com.ruoyi.common.utils.moonshot.vo;
+
+public class ChatCompletionMessage {
+    public String role;
+    public String name;
+    public String content;
+    public Boolean partial;
+
+    public ChatCompletionMessage(String role, String content) {
+        this.role = role;
+        this.content = content;
+    }
+
+    public ChatCompletionMessage(String role, String name, String content, Boolean partial) {
+        this.role = role;
+        this.name = name;
+        this.content = content;
+        this.partial = partial;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public Boolean getPartial() {
+        return partial;
+    }
+}

+ 42 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionRequest.java

@@ -0,0 +1,42 @@
+package com.ruoyi.common.utils.moonshot.vo;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.List;
+
+public class ChatCompletionRequest {
+    public String model;
+    public List<ChatCompletionMessage> messages;
+
+    @SerializedName("max_tokens")
+    public int maxTokens;
+
+    @SerializedName("temperature")
+    public float temperature;
+    public float topP;
+
+    public Integer n;
+    public boolean stream;
+    public List<String> stop;
+
+    @SerializedName("presence_penalty")
+    public float presencePenalty;
+
+    @SerializedName("frequency_penalty")
+    public float frequencyPenalty;
+
+    public String user;
+
+    public List<ChatCompletionMessage> getMessages() {
+        return messages;
+    }
+
+    public ChatCompletionRequest(String model, List<ChatCompletionMessage> messages, int maxTokens, float temperature, int n) {
+        this.model = model;
+        this.messages = messages;
+        this.maxTokens = maxTokens;
+        this.temperature = temperature;
+        this.n = n;
+    }
+
+}

+ 37 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionResponse.java

@@ -0,0 +1,37 @@
+package com.ruoyi.common.utils.moonshot.vo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ChatCompletionResponse {
+    private String id;
+    private String object;
+    private long created;
+    private String model;
+    private List<ChatCompletionChoice> choices;
+    private Usage usage;
+
+    public String getId() {
+        return id;
+    }
+
+    public String getObject() {
+        return object;
+    }
+
+    public long getCreated() {
+        return created;
+    }
+
+    public String getModel() {
+        return model;
+    }
+
+    public List<ChatCompletionChoice> getChoices() {
+        if (choices == null) {
+            return new ArrayList<ChatCompletionChoice>();
+        }
+        return choices;
+    }
+}
+

+ 51 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionStreamChoice.java

@@ -0,0 +1,51 @@
+package com.ruoyi.common.utils.moonshot.vo;
+
+import com.google.gson.annotations.SerializedName;
+
+public class ChatCompletionStreamChoice {
+    private int index;
+    private ChatCompletionStreamChoiceDelta delta;
+
+    @SerializedName("finish_reason")
+    private String finishReason;
+    private Usage usage;
+
+    public int getIndex() {
+        return index;
+    }
+
+    public ChatCompletionStreamChoiceDelta getDelta() {
+        return delta;
+    }
+
+    public String getFinishReason() {
+        return finishReason;
+    }
+
+    public Usage getUsage() {
+        return usage;
+    }
+
+    public void setIndex(int index) {
+        this.index = index;
+    }
+
+    public void setDelta(ChatCompletionStreamChoiceDelta delta) {
+        this.delta = delta;
+    }
+
+    public void setFinishReason(String finishReason) {
+        this.finishReason = finishReason;
+    }
+
+    public void setUsage(Usage usage) {
+        this.usage = usage;
+    }
+
+    public ChatCompletionStreamChoice(int index, ChatCompletionStreamChoiceDelta delta, String finishReason, Usage usage) {
+        this.index = index;
+        this.delta = delta;
+        this.finishReason = finishReason;
+        this.usage = usage;
+    }
+}

+ 27 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionStreamChoiceDelta.java

@@ -0,0 +1,27 @@
+package com.ruoyi.common.utils.moonshot.vo;
+
+public class ChatCompletionStreamChoiceDelta {
+    private String content;
+    private String role;
+
+    public String getContent() {
+        return content;
+    }
+
+    public String getRole() {
+        return role;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public void setRole(String role) {
+        this.role = role;
+    }
+
+    public ChatCompletionStreamChoiceDelta(String content, String role) {
+        this.content = content;
+        this.role = role;
+    }
+}

+ 43 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ChatCompletionStreamResponse.java

@@ -0,0 +1,43 @@
+package com.ruoyi.common.utils.moonshot.vo;
+
+import java.util.List;
+
+public class ChatCompletionStreamResponse {
+    private String id;
+    private String object;
+    private long created;
+    private String model;
+    private List<ChatCompletionStreamChoice> choices;
+
+    public String getId() {
+        return id;
+    }
+
+    public String getObject() {
+        return object;
+    }
+
+    public long getCreated() {
+        return created;
+    }
+
+    public String getModel() {
+        return model;
+    }
+
+    public List<ChatCompletionStreamChoice> getChoices() {
+        return choices;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public void setObject(String object) {
+        this.object = object;
+    }
+
+    public void setCreated(long created) {
+        this.created = created;
+    }
+}

+ 94 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/FileUploadResult.java

@@ -0,0 +1,94 @@
+package com.ruoyi.common.utils.moonshot.vo;
+
+public class FileUploadResult {
+
+    private String error;
+
+    private String id;
+
+    private String object;
+
+    private String bytes;
+
+    private String created_at;
+
+    private String filename;
+
+    private String purpose;
+
+    private String status;
+
+    private String status_details;
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getObject() {
+        return object;
+    }
+
+    public void setObject(String object) {
+        this.object = object;
+    }
+
+    public String getBytes() {
+        return bytes;
+    }
+
+    public void setBytes(String bytes) {
+        this.bytes = bytes;
+    }
+
+    public String getCreated_at() {
+        return created_at;
+    }
+
+    public void setCreated_at(String created_at) {
+        this.created_at = created_at;
+    }
+
+    public String getFilename() {
+        return filename;
+    }
+
+    public void setFilename(String filename) {
+        this.filename = filename;
+    }
+
+    public String getPurpose() {
+        return purpose;
+    }
+
+    public void setPurpose(String purpose) {
+        this.purpose = purpose;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getStatus_details() {
+        return status_details;
+    }
+
+    public void setStatus_details(String status_details) {
+        this.status_details = status_details;
+    }
+}

+ 61 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/Model.java

@@ -0,0 +1,61 @@
+package com.ruoyi.common.utils.moonshot.vo;
+
+import com.google.gson.annotations.SerializedName;
+
+public class Model {
+    private String id;
+    private String object;
+
+    @SerializedName("owner_by")
+    private String ownedBy;
+    private String root;
+    private String parent;
+
+    public String getId() {
+        return id;
+    }
+
+    public String getObject() {
+        return object;
+    }
+
+    public String getOwnedBy() {
+        return ownedBy;
+    }
+
+    public String getRoot() {
+        return root;
+    }
+
+    public String getParent() {
+        return parent;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public void setObject(String object) {
+        this.object = object;
+    }
+
+    public void setOwnedBy(String ownedBy) {
+        this.ownedBy = ownedBy;
+    }
+
+    public void setRoot(String root) {
+        this.root = root;
+    }
+
+    public void setParent(String parent) {
+        this.parent = parent;
+    }
+
+    public Model(String id, String object, String ownedBy, String root, String parent) {
+        this.id = id;
+        this.object = object;
+        this.ownedBy = ownedBy;
+        this.root = root;
+        this.parent = parent;
+    }
+}

+ 20 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/ModelsList.java

@@ -0,0 +1,20 @@
+package com.ruoyi.common.utils.moonshot.vo;
+
+import java.util.List;
+
+public class ModelsList {
+    private List<Model> data;
+
+    public List<Model> getData() {
+        return data;
+    }
+
+    public void setData(List<Model> data) {
+        this.data = data;
+    }
+
+    public ModelsList(List<Model> data) {
+        this.data = data;
+    }
+}
+

+ 19 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/moonshot/vo/Usage.java

@@ -0,0 +1,19 @@
+package com.ruoyi.common.utils.moonshot.vo;
+
+public class Usage {
+    private int promptTokens;
+    private int completionTokens;
+    private int totalTokens;
+
+    public int getPromptTokens() {
+        return promptTokens;
+    }
+
+    public int getCompletionTokens() {
+        return completionTokens;
+    }
+
+    public int getTotalTokens() {
+        return totalTokens;
+    }
+}