Home

Awesome

gpt-magic

This project is a Java library for GPT API, designed to make it easier for Java developers to use GPT API. <br> This is a community maintained project (an unofficial library)

Setup

maven

<dependency>
  <groupId>io.github.whitemagic2014</groupId>
  <artifactId>gpt-magic</artifactId>
  <version>version</version>
</dependency>

gradle

implementation group: 'io.github.whitemagic2014', name: 'gpt-magic', version: 'version'

short
implementation 'io.github.whitemagic2014:gpt-magic:version'

Feature

Keys

You can set the global key and proxy server as follows:

System.setProperty("OPENAI_API_KEY",""); // no system default value
System.setProperty("OPENAI_API_ORG","");// no system default value
System.setProperty("OPENAI_API_SERVER",""); // default = https://api.openai.com

Alternatively, you can configure them independently for each request.

new CreateChatCompletionRequest()
      .key("your api key")
      .server("default is https://api.openai.com")
      .organization("optional")
      .addMessage(ChatMessage.userMessage("prompt"));
      .send();

Support Apis

Demo

  System.setProperty("OPENAI_API_KEY", "");
  //System.setProperty("OPENAI_API_SERVER", "");// default is https://api.openai.com

  CreateChatCompletionRequest demo = new CreateChatCompletionRequest()
          .model(GptModel.gpt_3p5_turbo)
          .addMessage(ChatMessage.systemMessage("system set"))
          .addMessage(ChatMessage.userMessage("prompt"));
  // send with stream model
  String result1 = RequestUtil.streamRequest(demo);
  // send without stream model
  String result2 = demo2.sendForChoices().get(0).getMessage().getContent();

  // ...
  // See the code for more details

Version

1.12.1

1.12.0

1.11.0

1.10.4

Old
DefaultGptHttpUtil util = new DefaultGptHttpUtil();
New
DefaultGptHttpUtil util = DefaultGptHttpUtil.getInstance();

Old
DefaultGptHttpUtil util = new DefaultGptHttpUtil(true, 20000, 50000);
New
DefaultGptHttpUtil util = DefaultGptHttpUtil.getInstance();
util.init(true, 20000, 50000);

Additional Notes

1.10.3

1.10.2

1.10.1

Update: Added support for file search customizations. When using CreateVectorStoreFileRequest, you can specify the chunking_strategy parameter.

1.10.0

1.9.7

1.9.6

1.9.5

1.9.4

1.9.3

1.9.2

1.9.1

1.9.0

        //  Assistant simple demo
        //  https://platform.openai.com/docs/assistants/overview/agents
        // Step 1: Create an Assistant
        JSONObject json1 = new CreateAssistantRequest()
                .name("Math Tutor")
                .instructions("You are a personal math tutor. Write and run code to answer math questions.")
                .model(GptModel.gpt_4_turbo)
                .tools(Arrays.asList(new CodeInterpreterTool()))
                .send();
        System.out.println(json1);
        String assistantId = "assistantId";
        // Step 2: Create a Thread
        JSONObject json2 = new CreateThreadRequest().send();
        System.out.println(json2);
        String threadId = "threadId";
        // Step 3: Add a Message to a Thread
        JSONObject json3 = new CreateMessageRequest()
                .threadId(threadId)
                .content("I need to solve the equation `3x + 11 = 14`. Can you help me?")
                .send();
        System.out.println(json3);
        // Step 4: Run the Assistant
        JSONObject json4 = new CreateRunRequest()
                .assistantId(assistantId)
                .threadId(threadId)
                .instructions("Please address the user as WhiteMagic2014. The user has a premium account")
                .send();
        System.out.println(json4);
        String runId = "runId";
        // Step 5: Check the Run status
        JSONObject json5 = new RetrieveRunRequest().threadId(threadId).runId(runId).send();
        System.out.println(json5);
        // Step 6: Display the Assistant's Response
        JSONObject json6 = new ListMessagesRequest().threadId(threadId).send();
        System.out.println(json6);

1.8.0

    new CreateImageRequest()
        .prompt("xxxxxx")
        .model(GptModel.Dall_E_3)
        .styleVivid()
        .size1024x1024()
        .formatUrl()
        .sendForImages()
        .stream()
        .forEach(System.out::println);
    System.out.println(new CreateSpeechRequest().filePath("/path/to/save/file")
            .input("CreateSpeechRequest is available. It can trans text to speech.")
            .voice(AudioVoiceType.shimmer)
            .formatMp3()
            .send());
    // You can use base64 or URL to upload one or more images.
    System.out.println(new CreateChatCompletionRequest()
            .model(GptModel.gpt_4_vision_preview)
            // 2 url pictures
            .addMessage(ChatMessage.userMessageWithImageUrl("Which animal in these two pictures is stronger?",
                    Arrays.asList("https://pic1/url","https://pic2/url")))
            .maxTokens(300)
            .sendForChoices().get(0).getMessage().getContent());


    System.out.println(new CreateChatCompletionRequest()
            .model(GptModel.gpt_4_vision_preview)
            // 1 base64 pictures
            .addMessage(ChatMessage.userMessageWithImageFilePath("What does this picture describe",
                    Arrays.asList("/path/to/image/file.jpg")))
            .maxTokens(300)
            .sendForChoices().get(0).getMessage().getContent());

1.7.1

1.7.0

1.6.3

1.6.2

1.6.1

Explicitly setting in the request > Setting with System.setProperty > System default value.

System.setProperty("OPENAI_API_KEY",""); // no system default value
System.setProperty("OPENAI_API_ORG","");// no system default value
System.setProperty("OPENAI_API_SERVER",""); // default = https://api.openai.com

1.6.0

/**
 * your custom function
 * Get the current weather in a given location
 */
public JSONObject getCurrentWeather(String location, String unit) {
    JSONObject fakeResult = new JSONObject();
    fakeResult.put("location", location);
    if ("celsius".equals(unit)) {
        fakeResult.put("temperature", "22~31 C°");
    } else if ("fahrenheit".equals(unit)) {
        fakeResult.put("temperature", "71.6~87.8 F°");
    }
    fakeResult.put("forecast", Arrays.asList("sunny", "windy"));
    fakeResult.put("unit", unit);
    return fakeResult;
}

// A sample for function call
// first make a function object from your custom function method
ChatFunction function = JSONObject.parseObject("{\n" +
        "    \"name\":\"getCurrentWeather\",\n" +
        "    \"description\":\"Get the current weather in a given location\",\n" +
        "    \"parameters\":{\n" +
        "        \"type\":\"object\",\n" +
        "        \"required\":[\"location\",\"unit\"],\n" +
        "        \"properties\":{\n" +
        "            \"unit\":{\n" +
        "                \"default\":\"celsius\",\n" +
        "                \"type\":\"string\",\n" +
        "                \"enum\":[\"celsius\",\"fahrenheit\"]\n" +
        "            },\n" +
        "            \"location\":{\n" +
        "                \"description\":\"The city and state\",\n" +
        "                \"type\":\"string\"\n" +
        "            }\n" +
        "        }\n" +
        "    }\n" +
        "}", ChatFunction.class);
// second  send a CreateChatCompletionRequest with your Function
ChatMessage functionResult1 = new CreateChatCompletionRequest()
        .key(key)
        .addFunction(function)
        .model(GptModel.gpt_3p5_turbo_0613)
        .addMessage(ChatMessage.userMessage("What's the weather like in ShangHai today?"))
        .functionCallAuto() //.functionCallName("getCurrentWeather")
        .sendForChoices()
        .get(0)
        .getMessage();

// When using functionCallName or functionCallAuto to enable GPT to call a function,
// please note that the resulting output is temporary and not suitable for end users.
// To perform the desired action, you will need to call your custom function.
System.out.println("temp result:");
System.out.println(functionResult1);
// result eg:
// ChatMessage{role='assistant', content='null', name='null', function_call={"name":"getCurrentWeather","arguments":"{\n  \"location\": \"Shanghai\"\n}"}}

// If your function returns any information, you should call GPT again to obtain the final result for end users.
String functionName = functionResult1.getFunction_call().getString("name");
String location = functionResult1.getFunction_call().getJSONObject("arguments").getString("location");
String unit = functionResult1.getFunction_call().getJSONObject("arguments").getString("unit");
JSONObject weatherInfo = getCurrentWeather(location, unit);

// finally
ChatMessage functionResult2 = new CreateChatCompletionRequest()
        .key(key)
        .addFunction(function)
        .model(GptModel.gpt_3p5_turbo_0613)
        .addMessage(ChatMessage.userMessage("What's the weather like in ShangHai today?"))
        .addMessage(functionResult1)// gpt result
        .addMessage(ChatMessage.functionMessage(functionName, weatherInfo.toString())) // send a function message with function_name and custom result
        .sendForChoices()
        .get(0)
        .getMessage();
System.out.println("final result:");
System.out.println(functionResult2);
// result eg:
//ChatMessage{role='assistant', content='The weather in Shanghai today is sunny and windy, with a temperature ranging from 22 to 31 degrees Celsius.', name='null', function_call=null}

1.5.1

//  Now there are two ways to add a message.
new CreateChatCompletionRequest().addMessage("user","hello");
new CreateChatCompletionRequest().addMessage(ChatMessage.userMessage("hello"));

1.5.0

1.4.4

ChatMessage.systemMessage("content");
ChatMessage.userMessage("content");
ChatMessage.assistantMessage("content");

1.4.3

1.4.2

1.4.1

List<ChatCompletionChoice> demo8 = new CreateChatCompletionRequest()
    .server("https://Your.Proxy.Server/servername")
    .key(key)
    .addMessage("system", "You are a helpful assistant.")
    .addMessage("user", "Who won the world series in 2020?")
    .addMessage("assistant", "The Los Angeles Dodgers won the World Series in 2020.")
    .addMessage("user", "Where was it played?")
    .sendForChoices();

1.4

 // CreateChatCompletionRequest with stream mode
 // If you are providing a web service, you can offer HttpServletResponse.getOutputStream() 
 // so that you can provide your callers with OpenAI's streaming return, allowing them to easily achieve a typewriter effect similar to the OpenAI official page.
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  new Thread(() -> {
      new CreateChatCompletionRequest()
              .key(key)
              .addMessage("user", "Can you recommend some science fiction novels to me?")
              .stream(true)
              .outputStream(baos) // You need to set an OutputStream to receive the returned stream
              .send();
  }).start();
        
  // a sample to use the streaming return
  boolean flag = true;
  while (flag) {
      byte[] data = baos.toByteArray();
      if (data.length > 0) {
          String result = new String(data);
          baos.reset();
          String str = "[" + result.replace("data: [DONE]", "").replace("data:", ",") + "]";
          JSONArray jsonArray;
          try {
              jsonArray = JSON.parseArray(str);
          } catch (Exception e) {
              System.out.println(str);
              throw new RuntimeException(e);
          }
          for (int i = 0; i < jsonArray.size(); i++) {
              JSONObject choice = jsonArray.getJSONObject(i).getJSONArray("choices").getJSONObject(0);
              if ("stop".equals(choice.getString("finish_reason"))) {
                  flag = false;
                  break;
              }
              JSONObject delta = choice.getJSONObject("delta");
              if (delta.containsKey("content")) {
                  System.out.print(delta.getString("content"));
              }
          }
      }
      try {
          // wait for a while
          Thread.sleep(100);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
  }

1.3.3

1.3.2

1.3.1

version before 1.3.1
new CreateCompletionRequest().model("text-davinci-003");

version after 1.3.1
 new CreateCompletionRequest().model(GptModel.text_davinci_003);

1.3

1.2

1.1

License

This project is an open-sourced software licensed under the MIT license.