
io.github.m9d2.chatgpt.OpenAIService Maven / Gradle / Ivy
package io.github.m9d2.chatgpt;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.m9d2.chatgpt.framwork.constants.RequestParam;
import io.github.m9d2.chatgpt.framwork.enums.ContentType;
import io.github.m9d2.chatgpt.framwork.excption.ChatGPTException;
import io.github.m9d2.chatgpt.framwork.interceptor.AuthorizationInterceptor;
import io.github.m9d2.chatgpt.model.audio.AudioModel;
import io.github.m9d2.chatgpt.model.audio.AudioResponse;
import io.github.m9d2.chatgpt.model.billing.BillingUsage;
import io.github.m9d2.chatgpt.model.billing.Subscription;
import io.github.m9d2.chatgpt.model.chat.Completions;
import io.github.m9d2.chatgpt.model.chat.CompletionsResponse;
import io.github.m9d2.chatgpt.model.images.Images;
import io.github.m9d2.chatgpt.model.images.ImagesResponse;
import okhttp3.*;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSources;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.time.LocalDate;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
public class OpenAIService {
private final ChatGptConfig config;
private final OpenAIClient client;
private final OkHttpClient okHttpClient;
private final ObjectMapper objectMapper;
public OpenAIService(ChatGptConfig config) {
this.config = config;
this.okHttpClient = okHttpClient();
objectMapper = new ObjectMapper();
Retrofit retrofit = new Retrofit.Builder().baseUrl(OpenAIClient.URL).client(okHttpClient).addConverterFactory(JacksonConverterFactory.create()).build();
this.client = retrofit.create(OpenAIClient.class);
}
public String transcriptions(File file) {
return transcriptions(file, AudioModel.WHISPER_1, Locale.getDefault(), "");
}
public String transcriptions(File file, Locale locale) {
return transcriptions(file, AudioModel.WHISPER_1, locale, "");
}
public String transcriptions(File file, Locale locale, String prompt) {
return transcriptions(file, AudioModel.WHISPER_1, locale, prompt);
}
/**
* Transcribes audio into the input language.
*
* @param file The audio file object (not file name) to transcribe,
* in one of these formats: flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav, or webm.
* @param model ID of the model to use. Only whisper-1 is currently available.
* @param locale The language of the input audio.
* @param prompt An optional text to guide the model's style or continue a previous audio segment.
* The prompt should match the audio language.
* @return Transcriptions result
*/
public String transcriptions(File file, AudioModel model, Locale locale, String prompt) {
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(RequestParam.MODEL, model.getValue())
.addPart(createFile(file))
.addFormDataPart(RequestParam.LANGUAGE, locale.getLanguage())
.addFormDataPart(RequestParam.PROMPT, prompt)
.build();
Call call = this.client.transcriptions(requestBody);
return getAudioResponse(call);
}
public String translations(File file) {
return translations(file, AudioModel.WHISPER_1, "");
}
public String translations(File file, String prompt) {
return translations(file, AudioModel.WHISPER_1, prompt);
}
/**
* Translates audio into English.
*
* @param file The audio file object (not file name) translate,
* in one of these formats: flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav, or webm.
* @param model ID of the model to use. Only whisper-1 is currently available.
* @param prompt An optional text to guide the model's style or continue a previous audio segment.
* The prompt should be in English
* @return Translations result
*/
public String translations(File file, AudioModel model, String prompt) {
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(RequestParam.MODEL, model.getValue())
.addFormDataPart(RequestParam.PROMPT, prompt)
.addPart(createFile(file))
.build();
Call call = this.client.translations(requestBody);
return getAudioResponse(call);
}
private String getAudioResponse(Call call) {
Response response;
try {
response = call.execute();
} catch (IOException e) {
throw new RuntimeException(e);
}
if (!response.isSuccessful()) {
handleErrorResponse(response);
}
return Objects.requireNonNull(response.body()).getText();
}
private MultipartBody.Part createFile(File file) {
RequestBody fileBody = RequestBody.create(MediaType.parse(ContentType.MULTIPART.getValue()), file);
return MultipartBody.Part.createFormData(RequestParam.FILE, file.getName(), fileBody);
}
/**
* Creates a model response for the given chat conversation.
*
* @param completions params
*/
public CompletionsResponse completions(Completions completions) {
Call call = client.completions(completions);
Response response;
try {
response = call.execute();
} catch (IOException e) {
throw new ChatGPTException(e.getMessage());
}
if (!response.isSuccessful()) {
handleErrorResponse(response);
}
return response.body();
}
/**
* Creates a model response for the given chat conversation.
* Partial message deltas will be sent
*
* @param completions params
* @param consumerListener MessageListener instance
*/
public void completions(Completions completions, T consumerListener) {
completions.setStream(true);
EventSource.Factory factory = EventSources.createFactory(this.okHttpClient);
Request request;
try {
request = new Request.Builder()
.url(OpenAIClient.URL + "chat/completions")
.post(RequestBody.create(MediaType.parse(ContentType.JSON.getValue()), objectMapper.writeValueAsString(completions)))
.build();
} catch (JsonProcessingException e) {
throw new ChatGPTException(e.getMessage());
}
factory.newEventSource(request, consumerListener);
}
/**
* Subscription
*
* @return Subscription
*/
@Deprecated
public Subscription subscription() {
Call call = this.client.subscription();
Response response;
try {
response = call.execute();
} catch (IOException e) {
throw new RuntimeException(e);
}
if (!response.isSuccessful()) {
handleErrorResponse(response);
}
return response.body();
}
/**
* Billing usage
*
* @param starDate start date
* @param endDate end date
* @return BillingUsage
*/
@Deprecated
public BillingUsage billingUsage(LocalDate starDate, LocalDate endDate) {
Call call = this.client.billingUsage(starDate, endDate);
Response response;
try {
response = call.execute();
} catch (IOException e) {
throw new RuntimeException(e);
}
if (!response.isSuccessful()) {
handleErrorResponse(response);
}
return response.body();
}
/**
* Creates an image given a prompt.
*
* @param images images
*/
public ImagesResponse generations(Images images) {
Call call = client.generations(images);
Response response;
try {
response = call.execute();
} catch (IOException e) {
throw new RuntimeException(e);
}
if (!response.isSuccessful()) {
handleErrorResponse(response);
}
return response.body();
}
protected void handleErrorResponse(Response response) {
try (ResponseBody errorBody = response.errorBody()) {
if (errorBody == null) {
throw new ChatGPTException("response errorBody is null");
}
String errorMsg = errorBody.string();
throw new ChatGPTException(errorMsg);
} catch (IOException e) {
throw new ChatGPTException(e.getMessage());
}
}
private OkHttpClient okHttpClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (config.getProxy().getEnable()) {
builder.proxy(new Proxy(config.getProxy().getType(), new InetSocketAddress(config.getProxy().getHostname(), config.getProxy().getPort())));
}
builder.readTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS);
builder.connectTimeout(config.getConnectTimeout(), TimeUnit.MILLISECONDS);
builder.addInterceptor(AuthorizationInterceptor.getInstance(config.getApiKey()));
return builder.build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy