Skip to content

Commit 53f4fd4

Browse files
committed
add examples and dsl
1 parent 2896257 commit 53f4fd4

23 files changed

+625
-314
lines changed

examples/build.gradle.kts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
plugins {
2+
`java-library`
3+
kotlin("jvm") version "1.7.20-RC"
4+
}
5+
6+
repositories {
7+
mavenCentral()
8+
}
9+
10+
dependencies {
11+
implementation(project(":"))
12+
implementation("com.squareup.okhttp3:okhttp:4.9.2")
13+
implementation("com.fasterxml.jackson.core:jackson-core:2.15.3")
14+
implementation("com.fasterxml.jackson.core:jackson-databind:2.15.3")
15+
implementation("io.github.cdimascio:dotenv-kotlin:6.4.1")
16+
17+
// https://mvnrepository.com/artifact/org.mariuszgromada.math/MathParser.org-mXparser
18+
// Used for tool tests
19+
implementation("org.mariuszgromada.math:MathParser.org-mXparser:5.2.1")
20+
}
21+
22+
kotlin {
23+
jvmToolchain {
24+
languageVersion.set(JavaLanguageVersion.of(8))
25+
}
26+
}
27+
28+
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().all {
29+
kotlinOptions {
30+
jvmTarget = "1.8"
31+
}
32+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package chat;
2+
3+
import com.cjcrafter.openai.OpenAI;
4+
import com.cjcrafter.openai.chat.ChatMessage;
5+
import com.cjcrafter.openai.chat.ChatRequest;
6+
import com.cjcrafter.openai.chat.ChatResponse;
7+
import io.github.cdimascio.dotenv.Dotenv;
8+
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
import java.util.Scanner;
12+
13+
/**
14+
* In this Java example, we will be using the Chat API to create a simple chatbot.
15+
*/
16+
public class ChatCompletion {
17+
18+
public static void main(String[] args) {
19+
20+
// To use dotenv, you need to add the "io.github.cdimascio:dotenv-kotlin:version"
21+
// dependency. Then you can add a .env file in your project directory.
22+
String key = Dotenv.load().get("OPENAI_TOKEN");
23+
OpenAI openai = OpenAI.builder()
24+
.apiKey(key)
25+
.build();
26+
27+
List<ChatMessage> messages = new ArrayList<>();
28+
messages.add(ChatMessage.toSystemMessage("Help the user with their problem."));
29+
30+
// Here you can change the model's settings, add tools, and more.
31+
ChatRequest request = ChatRequest.builder()
32+
.model("gpt-3.5-turbo")
33+
.messages(messages)
34+
.build();
35+
36+
Scanner scan = new Scanner(System.in);
37+
while (true) {
38+
System.out.println("What are you having trouble with?");
39+
String input = scan.nextLine();
40+
41+
messages.add(ChatMessage.toUserMessage(input));
42+
ChatResponse response = openai.createChatCompletion(request);
43+
44+
System.out.println("Generating Response...");
45+
System.out.println(response.get(0).getMessage().getContent());
46+
47+
// Make sure to add the response to the messages list!
48+
messages.add(response.get(0).getMessage());
49+
}
50+
}
51+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package chat;
2+
3+
import com.cjcrafter.openai.OpenAI;
4+
import com.cjcrafter.openai.chat.ChatMessage;
5+
import com.cjcrafter.openai.chat.ChatRequest;
6+
import com.cjcrafter.openai.chat.ChatResponseChunk;
7+
import io.github.cdimascio.dotenv.Dotenv;
8+
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
import java.util.Scanner;
12+
13+
/**
14+
* In this Java example, we will be using the Chat API to create a simple chatbot.
15+
* Instead of waiting for the full response to generate, we will "stream" tokens
16+
* 1 by 1 as they are generated.
17+
*/
18+
public class StreamChatCompletion {
19+
20+
public static void main(String[] args) {
21+
22+
// To use dotenv, you need to add the "io.github.cdimascio:dotenv-kotlin:version"
23+
// dependency. Then you can add a .env file in your project directory.
24+
String key = Dotenv.load().get("OPENAI_TOKEN");
25+
OpenAI openai = OpenAI.builder()
26+
.apiKey(key)
27+
.build();
28+
29+
// Notice that this is a *mutable* list. We will be adding messages later
30+
// so we can continue the conversation.
31+
List<ChatMessage> messages = new ArrayList<>();
32+
messages.add(ChatMessage.toSystemMessage("Help the user with their problem."));
33+
34+
// Here you can change the model's settings, add tools, and more.
35+
ChatRequest request = ChatRequest.builder()
36+
.model("gpt-3.5-turbo")
37+
.messages(messages)
38+
.build();
39+
40+
Scanner scan = new Scanner(System.in);
41+
while (true) {
42+
System.out.println("What are you having trouble with?");
43+
String input = scan.nextLine();
44+
45+
messages.add(ChatMessage.toUserMessage(input));
46+
System.out.println("Generating Response...");
47+
48+
for (ChatResponseChunk chunk : openai.streamChatCompletion(request)) {
49+
// This is nullable! ChatGPT will return null AT LEAST ONCE PER MESSAGE.
50+
String delta = chunk.get(0).getDeltaContent();
51+
if (delta != null)
52+
System.out.print(delta);
53+
54+
// When the response is finished, we can add it to the messages list.
55+
if (chunk.get(0).isFinished())
56+
messages.add(chunk.get(0).getMessage());
57+
}
58+
59+
// Print a new line to separate the messages
60+
System.out.println();
61+
}
62+
}
63+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package chat;
2+
3+
import com.cjcrafter.openai.OpenAI;
4+
import com.cjcrafter.openai.chat.ChatMessage;
5+
import com.cjcrafter.openai.chat.ChatRequest;
6+
import com.cjcrafter.openai.chat.ChatResponseChunk;
7+
import com.cjcrafter.openai.chat.ChatUser;
8+
import com.cjcrafter.openai.chat.tool.*;
9+
import com.cjcrafter.openai.exception.HallucinationException;
10+
import com.fasterxml.jackson.databind.JsonNode;
11+
import io.github.cdimascio.dotenv.Dotenv;
12+
import org.mariuszgromada.math.mxparser.Expression;
13+
import org.mariuszgromada.math.mxparser.License;
14+
15+
import java.util.ArrayList;
16+
import java.util.List;
17+
import java.util.Map;
18+
import java.util.Scanner;
19+
20+
/**
21+
* In this Java example, we will be using the Chat API to create a simple chatbot.
22+
* Instead of waiting for the full response to generate, we will "stream" tokens
23+
* 1 by 1 as they are generated. We will also add a Math tool so that the chatbot
24+
* can solve math problems with a math parser.
25+
*/
26+
public class StreamChatCompletionFunction {
27+
28+
public static void main(String[] args) {
29+
30+
// Use mXparser
31+
License.iConfirmNonCommercialUse("CJCrafter");
32+
33+
// To use dotenv, you need to add the "io.github.cdimascio:dotenv-kotlin:version"
34+
// dependency. Then you can add a .env file in your project directory.
35+
String key = Dotenv.load().get("OPENAI_TOKEN");
36+
OpenAI openai = OpenAI.builder()
37+
.apiKey(key)
38+
.build();
39+
40+
// Notice that this is a *mutable* list. We will be adding messages later
41+
// so we can continue the conversation.
42+
List<ChatMessage> messages = new ArrayList<>();
43+
messages.add(ChatMessage.toSystemMessage("Help the user with their problem."));
44+
45+
// Here you can change the model's settings, add tools, and more.
46+
ChatRequest request = ChatRequest.builder()
47+
.model("gpt-3.5-turbo")
48+
.messages(messages)
49+
.addTool(FunctionTool.builder()
50+
.name("solve_math_problem")
51+
.description("Returns the result of a math problem as a double")
52+
.addStringParameter("equation", "The math problem for you to solve", true)
53+
.build()
54+
)
55+
.build();
56+
57+
Scanner scan = new Scanner(System.in);
58+
while (true) {
59+
System.out.println("What are you having trouble with?");
60+
String input = scan.nextLine();
61+
62+
messages.add(ChatMessage.toUserMessage(input));
63+
System.out.println("Generating Response...");
64+
65+
boolean madeToolCall;
66+
do {
67+
madeToolCall = false;
68+
for (ChatResponseChunk chunk : openai.streamChatCompletion(request)) {
69+
String delta = chunk.get(0).getDeltaContent();
70+
if (delta != null)
71+
System.out.print(delta);
72+
73+
// When the response is finished, we can add it to the messages list.
74+
if (chunk.get(0).isFinished())
75+
messages.add(chunk.get(0).getMessage());
76+
}
77+
78+
// If the API returned a tool call to us, we need to handle it.
79+
List<ToolCall> toolCalls = messages.get(messages.size() - 1).getToolCalls();
80+
if (toolCalls != null) {
81+
madeToolCall = true;
82+
for (ToolCall call : toolCalls) {
83+
ChatMessage response = handleToolCall(call, request.getTools());
84+
messages.add(response);
85+
}
86+
}
87+
88+
// Loop until we get a message without tool calls
89+
} while (madeToolCall);
90+
91+
// Print a new line to separate the messages
92+
System.out.println();
93+
}
94+
}
95+
96+
public static ChatMessage handleToolCall(ToolCall call, List<Tool> validTools) {
97+
// The try-catch here is *crucial*. ChatGPT *isn't very good*
98+
// at tool calls (And you probably aren't very good at prompt
99+
// engineering yet!). OpenAI will often "Hallucinate" arguments.
100+
try {
101+
if (call.getType() != ToolType.FUNCTION)
102+
throw new HallucinationException("Unknown tool call type: " + call.getType());
103+
104+
FunctionCall function = call.getFunction();
105+
Map<String, JsonNode> arguments = function.tryParseArguments(validTools); // You can pass null here for less strict parsing
106+
String equation = arguments.get("equation").asText();
107+
double result = solveEquation(equation);
108+
109+
// NaN implies that the equation was invalid
110+
if (Double.isNaN(result))
111+
throw new HallucinationException("Format was invalid: " + equation);
112+
113+
// Add the result to the messages list
114+
String json = "{\"result\": " + result + "}";
115+
return new ChatMessage(ChatUser.TOOL, json, null, call.getId());
116+
117+
} catch (HallucinationException ex) {
118+
119+
// Lets let ChatGPT know it made a mistake so it can correct itself
120+
String json = "{\"error\": \"" + ex.getMessage() + "\"}";
121+
return new ChatMessage(ChatUser.TOOL, json, null, call.getId());
122+
}
123+
}
124+
125+
public static double solveEquation(String equation) {
126+
Expression expression = new Expression(equation);
127+
return expression.calculate();
128+
}
129+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package completion;
2+
3+
import com.cjcrafter.openai.OpenAI;
4+
import com.cjcrafter.openai.completions.CompletionRequest;
5+
import io.github.cdimascio.dotenv.Dotenv;
6+
7+
/**
8+
* In this Java example, we will be using the Legacy Completion API to generate
9+
* a response.
10+
*/
11+
public class Completion {
12+
13+
public static void main(String[] args) {
14+
15+
// To use dotenv, you need to add the "io.github.cdimascio:dotenv-kotlin:version"
16+
// dependency. Then you can add a .env file in your project directory.
17+
String key = Dotenv.load().get("OPENAI_TOKEN");
18+
OpenAI openai = OpenAI.builder()
19+
.apiKey(key)
20+
.build();
21+
22+
String input = "What is 9+10?";
23+
24+
// We use 128 tokens, so we have minimal delay before the response (for testing).
25+
CompletionRequest request = CompletionRequest.builder()
26+
.model("davinci")
27+
.prompt(input)
28+
.maxTokens(128).build();
29+
30+
System.out.println("Generating Response...");
31+
String text = openai.createCompletion(request).get(0).getText();
32+
System.out.println(text);
33+
}
34+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package chat
2+
3+
import com.cjcrafter.openai.chat.*
4+
import com.cjcrafter.openai.chat.ChatMessage.Companion.toSystemMessage
5+
import com.cjcrafter.openai.chat.ChatMessage.Companion.toUserMessage
6+
import com.cjcrafter.openai.openAI
7+
import io.github.cdimascio.dotenv.dotenv
8+
import java.util.*
9+
10+
/**
11+
* In this Kotlin example, we will be using the Chat API to create a simple chatbot.
12+
*/
13+
fun main() {
14+
15+
// To use dotenv, you need to add the "io.github.cdimascio:dotenv-kotlin:version"
16+
// dependency. Then you can add a .env file in your project directory.
17+
val key = dotenv()["OPENAI_TOKEN"]
18+
val openai = openAI { apiKey(key) }
19+
20+
// Here you can change the model's settings, add tools, and more.
21+
val request = chatRequest {
22+
model("gpt-3.5-turbo")
23+
addMessage("Help the user with their problem.".toSystemMessage())
24+
}
25+
26+
val messages: MutableList<ChatMessage> = request.messages // We'll update this list as the conversation continues
27+
val scan = Scanner(System.`in`)
28+
while (true) {
29+
println("What are you having trouble with?")
30+
val input = scan.nextLine()
31+
messages.add(input.toUserMessage())
32+
println("Generating Response...")
33+
34+
val completion = openai.createChatCompletion(request)[0]
35+
println(completion.message.content)
36+
37+
messages.add(completion.message)
38+
}
39+
}

0 commit comments

Comments
 (0)