Client.java 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. package com.ruoyi.common.utils.moonshot;
  2. import com.google.gson.Gson;
  3. import com.ruoyi.common.utils.moonshot.vo.*;
  4. import io.reactivex.BackpressureStrategy;
  5. import io.reactivex.Flowable;
  6. import okhttp3.*;
  7. import org.springframework.web.multipart.MultipartFile;
  8. import java.io.File;
  9. import java.io.IOException;
  10. import java.util.Objects;
  11. import java.util.concurrent.TimeUnit;
  12. public class Client {
  13. private static final String DEFAULT_BASE_URL = "https://api.moonshot.cn/v1";
  14. private static final String CHAT_COMPLETION_SUFFIX = "/chat/completions";
  15. private static final String MODELS_SUFFIX = "/models";
  16. private static final String FILES_SUFFIX = "/files";
  17. private String baseUrl;
  18. private String apiKey;
  19. public Client(String apiKey) {
  20. this(apiKey, DEFAULT_BASE_URL);
  21. }
  22. public Client(String apiKey, String baseUrl) {
  23. this.apiKey = apiKey;
  24. if (baseUrl.endsWith("/")) {
  25. baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
  26. }
  27. this.baseUrl = baseUrl;
  28. }
  29. public String getChatCompletionUrl() {
  30. return baseUrl + CHAT_COMPLETION_SUFFIX;
  31. }
  32. public String getModelsUrl() {
  33. return baseUrl + MODELS_SUFFIX;
  34. }
  35. public String getFilesUrl() {
  36. return baseUrl + FILES_SUFFIX;
  37. }
  38. public String getApiKey() {
  39. return apiKey;
  40. }
  41. /**
  42. *
  43. * @return
  44. * @throws IOException
  45. */
  46. public ModelsList ListModels() throws IOException {
  47. OkHttpClient client = new OkHttpClient();
  48. Request request = new Request.Builder()
  49. .url(getModelsUrl())
  50. .addHeader("Authorization", "Bearer " + getApiKey())
  51. .build();
  52. try {
  53. Response response = client.newCall(request).execute();
  54. String body = response.body().string();
  55. Gson gson = new Gson();
  56. return gson.fromJson(body, ModelsList.class);
  57. } catch (IOException e) {
  58. e.printStackTrace();
  59. throw e;
  60. }
  61. }
  62. public String uploadFiles(File file) throws IOException {
  63. OkHttpClient client = new OkHttpClient();
  64. // 假设你有一个文件对象 "file" 需要上传
  65. // 这里还需要知道文件的MIME类型,这里以"application/octet-stream"为例,表示任意二进制数据
  66. MediaType MEDIA_TYPE_OCTET_STREAM = MediaType.parse("application/octet-stream");
  67. // 创建一个RequestBody来包装你的文件
  68. RequestBody fileBody = RequestBody.create(MEDIA_TYPE_OCTET_STREAM, file);
  69. // 使用MultipartBody.Builder来构建请求体
  70. MultipartBody.Builder multipartBuilder = new MultipartBody.Builder()
  71. .setType(MultipartBody.FORM)
  72. .addFormDataPart("file", file.getName(), fileBody); // "file" 是表单的键,通常与服务端约定
  73. // 如果还有其他表单字段,可以这样添加
  74. // .addFormDataPart("key", "value");
  75. MultipartBody multipartBody = multipartBuilder.build();
  76. // 使用multipartBody作为POST请求的请求体
  77. Request request = new Request.Builder()
  78. .url(getFilesUrl())
  79. .addHeader("Authorization", "Bearer " + getApiKey())
  80. .post(multipartBody)
  81. .build();
  82. try {
  83. Response response = client.newCall(request).execute();
  84. if (!response.isSuccessful()) {
  85. throw new IOException("Unexpected code " + response);
  86. }
  87. // 假设服务器返回的是JSON格式的响应
  88. return response.body().string();
  89. } catch (IOException e) {
  90. e.printStackTrace();
  91. throw e;
  92. }
  93. }
  94. public ChatCompletionResponse ChatCompletion(ChatCompletionRequest request) throws IOException {
  95. request.stream = false;
  96. OkHttpClient client = new OkHttpClient();
  97. MediaType mediaType = MediaType.parse("application/json");
  98. RequestBody body = RequestBody.create(mediaType, new Gson().toJson(request));
  99. Request httpRequest = new Request.Builder()
  100. .url(getChatCompletionUrl())
  101. .addHeader("Authorization", "Bearer " + getApiKey())
  102. .addHeader("Content-Type", "application/json")
  103. .post(body)
  104. .build();
  105. try {
  106. Response response = client.newCall(httpRequest).execute();
  107. String responseBody = response.body().string();
  108. Gson gson = new Gson();
  109. return gson.fromJson(responseBody, ChatCompletionResponse.class);
  110. } catch (IOException e) {
  111. e.printStackTrace();
  112. throw e;
  113. }
  114. }
  115. // return a stream of ChatCompletionStreamResponse
  116. public Flowable<ChatCompletionStreamResponse> ChatCompletionStream(ChatCompletionRequest request) throws IOException {
  117. request.stream = true;
  118. OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(30000, TimeUnit.SECONDS)
  119. .build();
  120. MediaType mediaType = MediaType.parse("application/json");
  121. RequestBody body = RequestBody.create(mediaType, new Gson().toJson(request));
  122. Request httpRequest = new Request.Builder()
  123. .url(getChatCompletionUrl())
  124. .addHeader("Authorization", "Bearer " + getApiKey())
  125. .addHeader("Content-Type", "application/json")
  126. .post(body)
  127. .build();
  128. Response response = client.newCall(httpRequest).execute();
  129. if (response.code() != 200) {
  130. throw new RuntimeException("Failed to start stream: " + response.body().string());
  131. }
  132. // get response body line by line
  133. return Flowable.create(emitter -> {
  134. ResponseBody responseBody = response.body();
  135. if (responseBody == null) {
  136. emitter.onError(new RuntimeException("Response body is null"));
  137. return;
  138. }
  139. String line;
  140. while ((line = responseBody.source().readUtf8Line()) != null) {
  141. if (line.startsWith("data:")) {
  142. line = line.substring(5);
  143. line = line.trim();
  144. }
  145. if (Objects.equals(line, "[DONE]")) {
  146. emitter.onComplete();
  147. return;
  148. }
  149. line = line.trim();
  150. if (line.isEmpty()) {
  151. continue;
  152. }
  153. Gson gson = new Gson();
  154. ChatCompletionStreamResponse streamResponse = gson.fromJson(line, ChatCompletionStreamResponse.class);
  155. emitter.onNext(streamResponse);
  156. }
  157. emitter.onComplete();
  158. }, BackpressureStrategy.BUFFER);
  159. }
  160. public FileUploadResult uploadFile(File file) throws IOException {
  161. OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(30000, TimeUnit.SECONDS)
  162. .build();
  163. RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
  164. .addFormDataPart("file",file.getPath(),
  165. RequestBody.create(MediaType.parse("application/octet-stream"),
  166. file))
  167. .addFormDataPart("purpose", "file-extract")
  168. .build();
  169. Request request = new Request.Builder()
  170. .url(getFilesUrl())
  171. .method("POST", body)
  172. .addHeader("Authorization", "Bearer " + getApiKey())
  173. .build();
  174. Response response = client.newCall(request).execute();
  175. String responseBody = response.body().string();
  176. Gson gson = new Gson();
  177. return gson.fromJson(responseBody, FileUploadResult.class);
  178. }
  179. public FileUploadResult uploadFile(MultipartFile file) throws IOException {
  180. OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(30000, TimeUnit.SECONDS)
  181. .build();
  182. RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
  183. .addFormDataPart("file",file.getOriginalFilename(),
  184. RequestBody.create(MediaType.parse("application/octet-stream"),
  185. file.getBytes()))
  186. .addFormDataPart("purpose", "file-extract")
  187. .build();
  188. Request request = new Request.Builder()
  189. .url(getFilesUrl())
  190. .method("POST", body)
  191. .addHeader("Authorization", "Bearer " + getApiKey())
  192. .build();
  193. Response response = client.newCall(request).execute();
  194. String responseBody = response.body().string();
  195. Gson gson = new Gson();
  196. return gson.fromJson(responseBody, FileUploadResult.class);
  197. }
  198. }