├── LICENSE ├── README.md ├── pom.xml └── src └── main ├── java └── io │ └── github │ └── flashvayne │ └── chatgpt │ ├── autoconfig │ └── ChatgptAutoConfiguration.java │ ├── dto │ ├── ChatRequest.java │ ├── ChatResponse.java │ ├── Choice.java │ ├── Usage.java │ ├── chat │ │ ├── MultiChatMessage.java │ │ ├── MultiChatRequest.java │ │ ├── MultiChatResponse.java │ │ └── MultiResponseChoice.java │ └── image │ │ ├── ImageData.java │ │ ├── ImageFormat.java │ │ ├── ImageRequest.java │ │ ├── ImageResponse.java │ │ └── ImageSize.java │ ├── exception │ └── ChatgptException.java │ ├── property │ ├── ChatgptProperties.java │ ├── ImageProperties.java │ └── MultiChatProperties.java │ └── service │ ├── ChatgptService.java │ └── impl │ └── DefaultChatgptService.java └── resources └── META-INF ├── spring-configuration-metadata.json ├── spring.factories └── spring └── org.springframework.boot.autoconfigure.AutoConfiguration.imports /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 vayne 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Maven central](https://maven-badges.herokuapp.com/maven-central/io.github.flashvayne/chatgpt-spring-boot-starter/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.github.flashvayne/chatgpt-spring-boot-starter) 2 | 3 | # chatgpt-spring-boot-starter 4 | This starter is based on OpenAi Official Apis. You can use chatgpt in springboot project easily. 5 | ## Functions: 6 | + Chat 7 | 8 | You can chat with ChatGPT using many models. Also, multi message is supported, so you can take a series of messages (including the conversation history) as input , and get a response message. 9 | 10 | + Image generation 11 | 12 | Give a prompt and get generated image(s). 13 | 14 | ## Usage 15 | ### 1.Add maven dependency. 16 | ```pom 17 | 18 | io.github.flashvayne 19 | chatgpt-spring-boot-starter 20 | 1.0.5 21 | 22 | ``` 23 | ### 2.Set chatgpt properties in your application.yml 24 | 25 | ```yml 26 | chatgpt: 27 | api-key: xxxxxxxxxxx #api-key. It can be generated here https://platform.openai.com/account/api-keys 28 | # some more properties(model,max-tokens...etc.) have default values. Also you can config them here. 29 | ``` 30 | ### 3.Inject bean ChatgptService anywhere you require it, and invoke its methods. 31 | #### 3.1 Chat 32 | 33 | ##### 3.1.1 Single message 34 | 35 | ```java 36 | @Autowired 37 | private ChatgptService chatgptService; 38 | 39 | public void test(){ 40 | String responseMessage = chatgptService.multiChat(Arrays.asList(new MultiChatMessage("user","how are you?"))); 41 | System.out.print(responseMessage); //\n\nAs an AI language model, I don't have feelings, but I'm functioning well. Thank you for asking. How can I assist you today? 42 | } 43 | 44 | public void test2(){ 45 | String responseMessage = chatgptService.sendMessage("how are you"); 46 | System.out.print(responseMessage); //I'm doing well, thank you. How about you? 47 | } 48 | ``` 49 | ##### 3.1.2 Multi message. You can take a series of messages (including the conversation history) as input , and return a response message as output. 50 | ```java 51 | @Autowired 52 | private ChatgptService chatgptService; 53 | 54 | public void testMultiChat(){ 55 | List messages = Arrays.asList( 56 | new MultiChatMessage("system","You are a helpful assistant."), 57 | new MultiChatMessage("user","Who won the world series in 2020?"), 58 | new MultiChatMessage("assistant","The Los Angeles Dodgers won the World Series in 2020."), 59 | new MultiChatMessage("user","Where was it played?")); 60 | String responseMessage = chatgptService.multiChat(messages); 61 | System.out.print(responseMessage); //The 2020 World Series was played at Globe Life Field in Arlington, Texas. 62 | } 63 | ``` 64 | + Tips: 65 | + Messages must be an array of message objects, where each object has a role (either "system", "user", or "assistant") and content (the content of the message). Conversations can be as short as 1 message or fill many pages. 66 | + The system message helps set the behavior of the assistant. In the example above, the assistant was instructed with "You are a helpful assistant." 67 | + The user messages help instruct the assistant. They can be generated by the end users of an application, or set by a developer as an instruction. 68 | + The assistant messages help store prior responses. They can also be written by a developer to help give examples of desired behavior. 69 | For more details, please refer to [chat format](https://platform.openai.com/docs/guides/chat/introduction) 70 | 71 | 72 | #### 3.2 Image generation 73 | ```java 74 | @Autowired 75 | private ChatgptService chatgptService; 76 | 77 | public void testImage(){ 78 | String imageUrl = chatgptService.imageGenerate("A cute baby sea otter"); 79 | System.out.print(imageUrl); //https://oaidalleapip....... 80 | } 81 | 82 | public void testImageList(){ 83 | List images = chatgptService.imageGenerate("A cute baby sea otter", 2, ImageSize.SMALL, ImageFormat.URL); 84 | System.out.print(images.toString());//["https://oaidalleapipr.....ZwA%3D","https://oaidalleapipr....RE0%3D"] 85 | } 86 | ``` 87 | 88 | ## Demo project: 89 | [demo-chatgpt-spring-boot-starter](https://github.com/flashvayne/demo-chatgpt-spring-boot-starter) 90 | 91 | # Author Info 92 | Email: flashvayne@gmail.com 93 | 94 | Blog: https://vayne.cc 95 | 96 | # Acknowledgments 97 | 98 | Thanks to JetBrains for their support of this project. They provided JetBrains Development Tool lisences for us. 99 | 100 | ![JetBrains Logo (Main) logo](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg) 101 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | io.github.flashvayne 8 | chatgpt-spring-boot-starter 9 | 1.0.5 10 | 11 | chatgpt-spring-boot-starter 12 | a starter to use chatgpt in springboot project easily 13 | https://github.com/flashvayne/chatgpt-spring-boot-starter 14 | 15 | 16 | 17 | The MIT License (MIT) 18 | https://github.com/flashvayne/chatgpt-spring-boot-starter/blob/master/LICENSE 19 | 20 | 21 | 22 | 23 | 24 | flashvayne 25 | flashvayne@gmail.com 26 | 27 | 28 | 29 | 30 | scm:git:git@github.com/flashvayne/chatgpt-spring-boot-starter.git 31 | scm:git:git@github.com/flashvayne/chatgpt-spring-boot-starter.git 32 | git@github.com/flashvayne/chatgpt-spring-boot-starter.git 33 | 34 | 35 | 36 | 1.8 37 | 2.17.1 38 | ${java.version} 39 | ${java.version} 40 | UTF-8 41 | UTF-8 42 | 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-autoconfigure 48 | 2.7.10 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-starter-web 54 | 2.7.10 55 | 56 | 57 | 58 | org.projectlombok 59 | lombok 60 | provided 61 | 1.18.26 62 | 63 | 64 | 65 | 66 | 67 | 68 | ossrh 69 | https://s01.oss.sonatype.org/content/repositories/snapshots 70 | 71 | 72 | ossrh 73 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/autoconfig/ChatgptAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.autoconfig; 2 | 3 | import io.github.flashvayne.chatgpt.property.ChatgptProperties; 4 | import io.github.flashvayne.chatgpt.service.ChatgptService; 5 | import io.github.flashvayne.chatgpt.service.impl.DefaultChatgptService; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 9 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | 13 | @Slf4j 14 | @Configuration 15 | @EnableConfigurationProperties(ChatgptProperties.class) 16 | public class ChatgptAutoConfiguration { 17 | 18 | private final ChatgptProperties chatgptProperties; 19 | 20 | @Autowired 21 | public ChatgptAutoConfiguration(ChatgptProperties chatgptProperties){ 22 | this.chatgptProperties = chatgptProperties; 23 | log.debug("chatgpt-springboot-starter loaded."); 24 | } 25 | 26 | @Bean 27 | @ConditionalOnMissingBean(ChatgptService.class) 28 | public ChatgptService chatgptService(){ 29 | return new DefaultChatgptService(chatgptProperties); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/ChatRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | * ChatRequest is used to construct request body. 13 | * For descriptions of all fields, please refer to Create completion 14 | */ 15 | @Data 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | @JsonInclude(JsonInclude.Include.NON_NULL) 19 | public class ChatRequest { 20 | 21 | private String model; 22 | 23 | private String prompt; 24 | 25 | @JsonProperty("max_tokens") 26 | private Integer maxTokens; 27 | 28 | private Double temperature; 29 | 30 | @JsonProperty("top_p") 31 | private Double topP; 32 | 33 | private String suffix; 34 | 35 | private Integer n; 36 | 37 | private Boolean stream; 38 | 39 | private Integer logprobs; 40 | 41 | private Boolean echo; 42 | 43 | private String stop; 44 | 45 | @JsonProperty("presence_penalty") 46 | private Double presencePenalty; 47 | 48 | @JsonProperty("frequency_penalty") 49 | private Double frequencyPenalty; 50 | 51 | @JsonProperty("best_of") 52 | private Integer bestOf; 53 | 54 | @JsonProperty("logit_bias") 55 | private Map logitBias; 56 | 57 | private String user; 58 | 59 | public ChatRequest(String model, String prompt, Integer maxTokens, Double temperature, Double topP) { 60 | this.model = model; 61 | this.prompt = prompt; 62 | this.maxTokens = maxTokens; 63 | this.temperature = temperature; 64 | this.topP = topP; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/ChatResponse.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDate; 6 | import java.util.List; 7 | 8 | @Data 9 | public class ChatResponse { 10 | private String id; 11 | private String object; 12 | private LocalDate created; 13 | private String model; 14 | private List choices; 15 | private Usage usage; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/Choice.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class Choice { 8 | private String text; 9 | private Integer index; 10 | private String logprobs; 11 | 12 | @JsonProperty("finish_reason") 13 | private String finishReason; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/Usage.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class Usage { 8 | 9 | @JsonProperty("prompt_tokens") 10 | private Integer promptTokens; 11 | 12 | @JsonProperty("completion_tokens") 13 | private Integer completionTokens; 14 | 15 | @JsonProperty("total_tokens") 16 | private Integer totalTokens; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/chat/MultiChatMessage.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto.chat; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | public class MultiChatMessage { 11 | private String role; 12 | private String content; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/chat/MultiChatRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto.chat; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * MultiChatRequest is used to construct request body. 14 | * For descriptions of all fields, please refer to Create chat completion 15 | */ 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | @JsonInclude(JsonInclude.Include.NON_NULL) 20 | public class MultiChatRequest { 21 | private String model; 22 | 23 | private List messages; 24 | 25 | /** 26 | * The maximum number of tokens to generate in the completion. 27 | * The token count of your prompt plus max_tokens cannot exceed the model's context length. 28 | * Most models have a context length of 2048 tokens (except for the newest models, which support 4096). 29 | */ 30 | @JsonProperty("max_tokens") 31 | private Integer maxTokens; 32 | 33 | private Double temperature; 34 | 35 | @JsonProperty("top_p") 36 | private Double topP; 37 | 38 | private Integer n; 39 | 40 | private Boolean stream; 41 | 42 | private String stop; 43 | 44 | @JsonProperty("presence_penalty") 45 | private Double presencePenalty; 46 | 47 | @JsonProperty("frequency_penalty") 48 | private Double frequencyPenalty; 49 | 50 | @JsonProperty("logit_bias") 51 | private Map logitBias; 52 | 53 | private String user; 54 | 55 | public MultiChatRequest(String model, List messages, Integer maxTokens, Double temperature, Double topP) { 56 | this.model = model; 57 | this.messages = messages; 58 | this.maxTokens = maxTokens; 59 | this.temperature = temperature; 60 | this.topP = topP; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/chat/MultiChatResponse.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto.chat; 2 | 3 | import io.github.flashvayne.chatgpt.dto.Usage; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDate; 9 | import java.util.List; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class MultiChatResponse { 15 | private String id; 16 | private String object; 17 | private LocalDate created; 18 | private String model; 19 | private List choices; 20 | private Usage usage; 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/chat/MultiResponseChoice.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto.chat; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @NoArgsConstructor 10 | @AllArgsConstructor 11 | public class MultiResponseChoice { 12 | private MultiChatMessage message; 13 | 14 | @JsonProperty("finish_reason") 15 | private String finishReason; 16 | 17 | private Integer index; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/image/ImageData.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto.image; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class ImageData { 8 | private String url; 9 | 10 | @JsonProperty("b64_json") 11 | private String b64Json; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/image/ImageFormat.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto.image; 2 | 3 | public enum ImageFormat { 4 | 5 | URL("url"),BASE64("b64_json"); 6 | 7 | private final String format; 8 | 9 | ImageFormat(String format){ 10 | this.format = format; 11 | } 12 | 13 | public String getFormat(){ 14 | return format; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/image/ImageRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto.image; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | /** 10 | * ImageRequest is used to construct request body. 11 | * For descriptions of all fields, please refer to Create image 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @JsonInclude(JsonInclude.Include.NON_NULL) 17 | public class ImageRequest { 18 | 19 | private String prompt; 20 | private Integer n; 21 | private String size; 22 | 23 | @JsonProperty("response_format") 24 | private String responseFormat; 25 | 26 | private String user; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/image/ImageResponse.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto.image; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Date; 8 | import java.util.List; 9 | 10 | @Data 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class ImageResponse { 14 | private Date created; 15 | 16 | private List data; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/dto/image/ImageSize.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.dto.image; 2 | 3 | public enum ImageSize { 4 | 5 | SMALL("256x256"), MEDIUM("512x512"), LARGE("1024x1024"); 6 | 7 | private final String size; 8 | 9 | ImageSize(String size) { 10 | this.size = size; 11 | } 12 | 13 | public String getSize() { 14 | return size; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/exception/ChatgptException.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.exception; 2 | 3 | public class ChatgptException extends RuntimeException{ 4 | 5 | public ChatgptException(){ 6 | super(); 7 | } 8 | 9 | public ChatgptException(String message){ 10 | super(message); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/property/ChatgptProperties.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.property; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | @ConfigurationProperties(prefix = "chatgpt") 8 | public class ChatgptProperties { 9 | 10 | private String apiKey = ""; 11 | 12 | private String url = "https://api.openai.com/v1/completions"; 13 | 14 | private String model = "gpt-3.5-turbo-instruct"; 15 | 16 | private Integer maxTokens = 500; 17 | 18 | private Double temperature = 1.0; 19 | 20 | private Double topP = 1.0; 21 | 22 | private MultiChatProperties multi; 23 | 24 | private ImageProperties image; 25 | 26 | public ChatgptProperties() { 27 | this.multi = new MultiChatProperties(); 28 | this.image = new ImageProperties(); 29 | } 30 | 31 | public String getApiKey() { 32 | return apiKey; 33 | } 34 | 35 | public void setApiKey(String apiKey) { 36 | this.apiKey = apiKey; 37 | } 38 | 39 | public String getUrl() { 40 | return url; 41 | } 42 | 43 | public void setUrl(String url) { 44 | this.url = url; 45 | } 46 | 47 | public String getModel() { 48 | return model; 49 | } 50 | 51 | public void setModel(String model) { 52 | this.model = model; 53 | } 54 | 55 | public Integer getMaxTokens() { 56 | return maxTokens; 57 | } 58 | 59 | public void setMaxTokens(Integer maxTokens) { 60 | this.maxTokens = maxTokens; 61 | } 62 | 63 | public Double getTemperature() { 64 | return temperature; 65 | } 66 | 67 | public void setTemperature(Double temperature) { 68 | this.temperature = temperature; 69 | } 70 | 71 | public Double getTopP() { 72 | return topP; 73 | } 74 | 75 | public void setTopP(Double topP) { 76 | this.topP = topP; 77 | } 78 | 79 | public MultiChatProperties getMulti() { 80 | return multi; 81 | } 82 | 83 | public void setMulti(MultiChatProperties multi) { 84 | this.multi = multi; 85 | } 86 | 87 | public ImageProperties getImage() { 88 | return image; 89 | } 90 | 91 | public void setImage(ImageProperties image) { 92 | this.image = image; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/property/ImageProperties.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.property; 2 | 3 | public class ImageProperties { 4 | 5 | private String url = "https://api.openai.com/v1/images/generations"; 6 | 7 | public String getUrl() { 8 | return url; 9 | } 10 | 11 | public void setUrl(String url) { 12 | this.url = url; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/property/MultiChatProperties.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.property; 2 | 3 | public class MultiChatProperties { 4 | 5 | private String url = "https://api.openai.com/v1/chat/completions"; 6 | 7 | private String model = "gpt-3.5-turbo"; 8 | 9 | private Integer maxTokens = 500; 10 | 11 | private Double temperature = 1.0; 12 | 13 | private Double topP = 1.0; 14 | 15 | public String getUrl() { 16 | return url; 17 | } 18 | 19 | public void setUrl(String url) { 20 | this.url = url; 21 | } 22 | 23 | public String getModel() { 24 | return model; 25 | } 26 | 27 | public void setModel(String model) { 28 | this.model = model; 29 | } 30 | 31 | public Integer getMaxTokens() { 32 | return maxTokens; 33 | } 34 | 35 | public void setMaxTokens(Integer maxTokens) { 36 | this.maxTokens = maxTokens; 37 | } 38 | 39 | public Double getTemperature() { 40 | return temperature; 41 | } 42 | 43 | public void setTemperature(Double temperature) { 44 | this.temperature = temperature; 45 | } 46 | 47 | public Double getTopP() { 48 | return topP; 49 | } 50 | 51 | public void setTopP(Double topP) { 52 | this.topP = topP; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/service/ChatgptService.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.service; 2 | 3 | import io.github.flashvayne.chatgpt.dto.ChatRequest; 4 | import io.github.flashvayne.chatgpt.dto.ChatResponse; 5 | import io.github.flashvayne.chatgpt.dto.chat.MultiChatMessage; 6 | import io.github.flashvayne.chatgpt.dto.chat.MultiChatRequest; 7 | import io.github.flashvayne.chatgpt.dto.chat.MultiChatResponse; 8 | import io.github.flashvayne.chatgpt.dto.image.ImageFormat; 9 | import io.github.flashvayne.chatgpt.dto.image.ImageRequest; 10 | import io.github.flashvayne.chatgpt.dto.image.ImageResponse; 11 | import io.github.flashvayne.chatgpt.dto.image.ImageSize; 12 | 13 | import java.util.List; 14 | 15 | public interface ChatgptService { 16 | 17 | String sendMessage(String message); 18 | 19 | ChatResponse sendChatRequest(ChatRequest request); 20 | 21 | String multiChat(List messages); 22 | 23 | MultiChatResponse multiChatRequest(MultiChatRequest multiChatRequest); 24 | 25 | /** 26 | * @param prompt A text description of the desired image(s). The maximum length is 1000 characters. 27 | * @return generated image url 28 | */ 29 | String imageGenerate(String prompt); 30 | 31 | /** 32 | * @param prompt A text description of the desired image(s). The maximum length is 1000 characters. 33 | * @param n The number of images to generate. Must be between 1 and 10. 34 | * @param size The size of the generated images. Must be one of ImageFormat.SMALL("256x256"), ImageFormat.MEDIUM("512x512"), ImageFormat.LARGE("1024x1024"). 35 | * @param format The format in which the generated images are returned. Must be one of ImageFormat.URL("url"), ImageFormat.BASE64("b64_json"). 36 | * @return image url/base64 list 37 | */ 38 | List imageGenerate(String prompt, Integer n, ImageSize size, ImageFormat format); 39 | 40 | ImageResponse imageGenerateRequest(ImageRequest imageRequest); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/io/github/flashvayne/chatgpt/service/impl/DefaultChatgptService.java: -------------------------------------------------------------------------------- 1 | package io.github.flashvayne.chatgpt.service.impl; 2 | 3 | import io.github.flashvayne.chatgpt.dto.ChatRequest; 4 | import io.github.flashvayne.chatgpt.dto.chat.MultiChatMessage; 5 | import io.github.flashvayne.chatgpt.dto.chat.MultiChatRequest; 6 | import io.github.flashvayne.chatgpt.dto.chat.MultiChatResponse; 7 | import io.github.flashvayne.chatgpt.dto.image.*; 8 | import io.github.flashvayne.chatgpt.exception.ChatgptException; 9 | import io.github.flashvayne.chatgpt.property.ChatgptProperties; 10 | import io.github.flashvayne.chatgpt.dto.ChatResponse; 11 | import io.github.flashvayne.chatgpt.service.ChatgptService; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.http.*; 14 | import org.springframework.stereotype.Service; 15 | import org.springframework.web.client.RestTemplate; 16 | 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | 21 | @Slf4j 22 | @Service 23 | public class DefaultChatgptService implements ChatgptService { 24 | 25 | protected final ChatgptProperties chatgptProperties; 26 | 27 | private final String AUTHORIZATION; 28 | 29 | private final RestTemplate restTemplate = new RestTemplate(); 30 | 31 | public DefaultChatgptService(ChatgptProperties chatgptProperties) { 32 | this.chatgptProperties = chatgptProperties; 33 | AUTHORIZATION = "Bearer " + chatgptProperties.getApiKey(); 34 | } 35 | 36 | @Override 37 | public String sendMessage(String message) { 38 | ChatRequest chatRequest = new ChatRequest(chatgptProperties.getModel(), message, chatgptProperties.getMaxTokens(), chatgptProperties.getTemperature(), chatgptProperties.getTopP()); 39 | ChatResponse chatResponse = this.getResponse(this.buildHttpEntity(chatRequest), ChatResponse.class, chatgptProperties.getUrl()); 40 | try { 41 | return chatResponse.getChoices().get(0).getText(); 42 | } catch (Exception e) { 43 | log.error("parse chatgpt message error", e); 44 | throw e; 45 | } 46 | } 47 | 48 | @Override 49 | public ChatResponse sendChatRequest(ChatRequest chatRequest) { 50 | return this.getResponse(this.buildHttpEntity(chatRequest), ChatResponse.class, chatgptProperties.getUrl()); 51 | } 52 | 53 | @Override 54 | public String multiChat(List messages) { 55 | MultiChatRequest multiChatRequest = new MultiChatRequest(chatgptProperties.getMulti().getModel(), messages, chatgptProperties.getMulti().getMaxTokens(), chatgptProperties.getMulti().getTemperature(), chatgptProperties.getMulti().getTopP()); 56 | MultiChatResponse multiChatResponse = this.getResponse(this.buildHttpEntity(multiChatRequest), MultiChatResponse.class, chatgptProperties.getMulti().getUrl()); 57 | try { 58 | return multiChatResponse.getChoices().get(0).getMessage().getContent(); 59 | } catch (Exception e) { 60 | log.error("parse chatgpt message error", e); 61 | throw e; 62 | } 63 | } 64 | 65 | @Override 66 | public MultiChatResponse multiChatRequest(MultiChatRequest multiChatRequest) { 67 | return this.getResponse(this.buildHttpEntity(multiChatRequest), MultiChatResponse.class, chatgptProperties.getMulti().getUrl()); 68 | } 69 | 70 | @Override 71 | public String imageGenerate(String prompt) { 72 | ImageRequest imageRequest = new ImageRequest(prompt, null, null, null, null); 73 | ImageResponse imageResponse = this.getResponse(this.buildHttpEntity(imageRequest), ImageResponse.class, chatgptProperties.getImage().getUrl()); 74 | try { 75 | return imageResponse.getData().get(0).getUrl(); 76 | } catch (Exception e) { 77 | log.error("parse image url error", e); 78 | throw e; 79 | } 80 | } 81 | 82 | @Override 83 | public List imageGenerate(String prompt, Integer n, ImageSize size, ImageFormat format) { 84 | ImageRequest imageRequest = new ImageRequest(prompt, n, size.getSize(), format.getFormat(), null); 85 | ImageResponse imageResponse = this.getResponse(this.buildHttpEntity(imageRequest), ImageResponse.class, chatgptProperties.getImage().getUrl()); 86 | try { 87 | List list = new ArrayList<>(); 88 | imageResponse.getData().forEach(imageData -> { 89 | if (format.equals(ImageFormat.URL)) { 90 | list.add(imageData.getUrl()); 91 | } else { 92 | list.add(imageData.getB64Json()); 93 | } 94 | }); 95 | return list; 96 | } catch (Exception e) { 97 | log.error("parse image url error", e); 98 | throw e; 99 | } 100 | } 101 | 102 | @Override 103 | public ImageResponse imageGenerateRequest(ImageRequest imageRequest) { 104 | return this.getResponse(this.buildHttpEntity(imageRequest), ImageResponse.class, chatgptProperties.getImage().getUrl()); 105 | } 106 | 107 | protected HttpEntity buildHttpEntity(T request) { 108 | HttpHeaders headers = new HttpHeaders(); 109 | headers.setContentType(MediaType.parseMediaType("application/json; charset=UTF-8")); 110 | headers.add("Authorization", AUTHORIZATION); 111 | return new HttpEntity<>(request, headers); 112 | } 113 | 114 | protected T getResponse(HttpEntity httpEntity, Class responseType, String url) { 115 | log.info("request url: {}, httpEntity: {}", url, httpEntity); 116 | ResponseEntity responseEntity = restTemplate.postForEntity(url, httpEntity, responseType); 117 | if (responseEntity.getStatusCodeValue() != HttpStatus.OK.value()) { 118 | log.error("error response status: {}", responseEntity); 119 | throw new ChatgptException("error response status :" + responseEntity.getStatusCodeValue()); 120 | } else { 121 | log.info("response: {}", responseEntity); 122 | } 123 | return responseEntity.getBody(); 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "groups": [ 3 | { 4 | "name": "chatgpt", 5 | "type": "io.github.flashvayne.chatgpt.property.ChatgptProperties", 6 | "sourceType": "io.github.flashvayne.chatgpt.property.ChatgptProperties" 7 | } 8 | ], 9 | "properties": [ 10 | { 11 | "name": "chatgpt.api-key", 12 | "type": "java.lang.String", 13 | "sourceType": "io.github.flashvayne.chatgpt.property.ChatgptProperties", 14 | "defaultValue": "", 15 | "description": "apiKey of chatgpt. It can be generated in this link https://platform.openai.com/account/api-keys", 16 | "required": true 17 | }, 18 | { 19 | "name": "chatgpt.model", 20 | "type": "java.lang.String", 21 | "sourceType": "io.github.flashvayne.chatgpt.property.ChatgptProperties", 22 | "defaultValue": "gpt-3.5-turbo-instruct", 23 | "description": "ID of the model to use. You can see our Model overview (https://platform.openai.com/docs/models/overview) for descriptions of them." 24 | }, 25 | { 26 | "name": "chatgpt.url", 27 | "type": "java.lang.String", 28 | "sourceType": "io.github.flashvayne.chatgpt.property.ChatgptProperties", 29 | "defaultValue": "https://api.openai.com/v1/completions", 30 | "description": "The request url." 31 | }, 32 | { 33 | "name": "chatgpt.max-tokens", 34 | "type": "java.lang.Integer", 35 | "sourceType": "io.github.flashvayne.chatgpt.property.ChatgptProperties", 36 | "defaultValue": 500, 37 | "description": "The maximum number of tokens to generate in the completion.The token count of your prompt plus max_tokens cannot exceed the model's context length. Most models have a context length of 2048 tokens (except for the newest models, which support 4096)." 38 | },{ 39 | "name": "chatgpt.temperature", 40 | "type": "java.lang.Double", 41 | "sourceType": "io.github.flashvayne.chatgpt.property.ChatgptProperties", 42 | "defaultValue": "1.0", 43 | "description": "What sampling temperature to use. Higher values means the model will take more risks. Try 0.9 for more creative applications, and 0 (argmax sampling) for ones with a well-defined answer.We generally recommend altering this or top_p but not both." 44 | },{ 45 | "name": "chatgpt.top-p", 46 | "type": "java.lang.Double", 47 | "sourceType": "io.github.flashvayne.chatgpt.property.ChatgptProperties", 48 | "defaultValue": "1.0", 49 | "description": "An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.We generally recommend altering this or temperature but not both." 50 | }, 51 | 52 | { 53 | "name": "chatgpt.multi.model", 54 | "type": "java.lang.String", 55 | "sourceType": "io.github.flashvayne.chatgpt.property.MultiChatProperties", 56 | "defaultValue": "gpt-3.5-turbo", 57 | "description": "ID of the model to use. See the model endpoint compatibility (https://platform.openai.com/docs/models/model-endpoint-compatibility) table for details on which models work with the Chat API." 58 | }, 59 | { 60 | "name": "chatgpt.multi.url", 61 | "type": "java.lang.String", 62 | "sourceType": "io.github.flashvayne.chatgpt.property.MultiChatProperties", 63 | "defaultValue": "https://api.openai.com/v1/chat/completions", 64 | "description": "The request url." 65 | }, 66 | { 67 | "name": "chatgpt.multi.max-tokens", 68 | "type": "java.lang.Integer", 69 | "sourceType": "io.github.flashvayne.chatgpt.property.MultiChatProperties", 70 | "defaultValue": 500, 71 | "description": "The maximum number of tokens to generate in the chat completion.\n\nThe total length of input tokens and generated tokens is limited by the model's context length." 72 | },{ 73 | "name": "chatgpt.multi.temperature", 74 | "type": "java.lang.Double", 75 | "sourceType": "io.github.flashvayne.chatgpt.property.MultiChatProperties", 76 | "defaultValue": "1.0", 77 | "description": "What sampling temperature to use. Higher values means the model will take more risks. Try 0.9 for more creative applications, and 0 (argmax sampling) for ones with a well-defined answer.We generally recommend altering this or top_p but not both." 78 | },{ 79 | "name": "chatgpt.multi.top-p", 80 | "type": "java.lang.Double", 81 | "sourceType": "io.github.flashvayne.chatgpt.property.MultiChatProperties", 82 | "defaultValue": "1.0", 83 | "description": "An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.We generally recommend altering this or temperature but not both." 84 | },{ 85 | "name": "chatgpt.image.url", 86 | "type": "java.lang.String", 87 | "sourceType": "io.github.flashvayne.chatgpt.property.ImageProperties", 88 | "defaultValue": "https://api.openai.com/v1/images/generations", 89 | "description": "The request url." 90 | } 91 | ], 92 | "hints": [] 93 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration =\ 2 | io.github.flashvayne.chatgpt.autoconfig.ChatgptAutoConfiguration -------------------------------------------------------------------------------- /src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | io.github.flashvayne.chatgpt.autoconfig.ChatgptAutoConfiguration --------------------------------------------------------------------------------