├── 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 | [](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 | 
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
--------------------------------------------------------------------------------