Skip to content
This repository was archived by the owner on Jun 6, 2024. It is now read-only.

Commit d1f2748

Browse files
authored
Add moderation support (#24)
Adding support for the new Moderations api https://beta.openai.com/docs/guides/moderation Fixes #20
1 parent 77219d4 commit d1f2748

File tree

10 files changed

+195
-7
lines changed

10 files changed

+195
-7
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ as well as an example project using the client.
1212
- [Engines](https://beta.openai.com/docs/api-reference/engines)
1313
- [Completions](https://beta.openai.com/docs/api-reference/completions)
1414
- [Edits](https://beta.openai.com/docs/api-reference/edits)
15+
- [Embeddings](https://beta.openai.com/docs/api-reference/embeddings)
1516
- [Searches](https://beta.openai.com/docs/api-reference/searches)
1617
- [Classifications](https://beta.openai.com/docs/api-reference/classifications)
1718
- [Answers](https://beta.openai.com/docs/api-reference/answers)
1819
- [Files](https://beta.openai.com/docs/api-reference/files)
1920
- [Fine-tunes](https://beta.openai.com/docs/api-reference/fine-tunes)
20-
- [Embeddings](https://beta.openai.com/docs/api-reference/embeddings)
21+
- [Moderations](https://beta.openai.com/docs/api-reference/moderations)
2122

2223
## Usage
2324

api/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ apply plugin: 'java-library'
22
apply plugin: "com.vanniktech.maven.publish"
33

44
dependencies {
5+
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.9.0'
56
compileOnly 'org.projectlombok:lombok:1.18.12'
67
annotationProcessor 'org.projectlombok:lombok:1.18.12'
78
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.theokanning.openai.moderation;
2+
3+
import lombok.Data;
4+
5+
/**
6+
* An object containing the moderation data for a single input string
7+
*
8+
* https://beta.openai.com/docs/api-reference/moderations/create
9+
*/
10+
@Data
11+
public class Moderation {
12+
/**
13+
* Set to true if the model classifies the content as violating OpenAI's content policy, false otherwise
14+
*/
15+
boolean flagged;
16+
17+
/**
18+
* Object containing per-category binary content policy violation flags.
19+
* For each category, the value is true if the model flags the corresponding category as violated, false otherwise.
20+
*/
21+
ModerationCategories categories;
22+
23+
/**
24+
* Object containing per-category raw scores output by the model, denoting the model's confidence that the
25+
* input violates the OpenAI's policy for the category.
26+
* The value is between 0 and 1, where higher values denote higher confidence.
27+
* The scores should not be interpreted as probabilities.
28+
*/
29+
ModerationCategoryScores categoryScores;
30+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.theokanning.openai.moderation;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.theokanning.openai.completion.CompletionChoice;
5+
import lombok.Data;
6+
7+
import java.util.List;
8+
9+
/**
10+
* An object containing the flags for each moderation category
11+
*
12+
* https://beta.openai.com/docs/api-reference/moderations/create
13+
*/
14+
@Data
15+
public class ModerationCategories {
16+
17+
boolean hate;
18+
19+
@JsonProperty("hate/threatening")
20+
boolean hateThreatening;
21+
22+
@JsonProperty("self-harm")
23+
boolean selfHarm;
24+
25+
boolean sexual;
26+
27+
@JsonProperty("sexual/minors")
28+
boolean sexualMinors;
29+
30+
boolean violence;
31+
32+
@JsonProperty("violence/graphic")
33+
boolean violenceGraphic;
34+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.theokanning.openai.moderation;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import lombok.Data;
5+
6+
/**
7+
* An object containing the scores for each moderation category
8+
*
9+
* https://beta.openai.com/docs/api-reference/moderations/create
10+
*/
11+
@Data
12+
public class ModerationCategoryScores {
13+
14+
double hate;
15+
16+
@JsonProperty("hate/threatening")
17+
double hateThreatening;
18+
19+
@JsonProperty("self-harm")
20+
double selfHarm;
21+
22+
double sexual;
23+
24+
@JsonProperty("sexual/minors")
25+
double sexualMinors;
26+
27+
double violence;
28+
29+
@JsonProperty("violence/graphic")
30+
double violenceGraphic;
31+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.theokanning.openai.moderation;
2+
3+
import lombok.*;
4+
5+
import java.util.List;
6+
7+
/**
8+
* A request for OpenAi to detect if text violates OpenAi's content policy.
9+
*
10+
* https://beta.openai.com/docs/api-reference/moderations/create
11+
*/
12+
@Builder
13+
@NoArgsConstructor
14+
@AllArgsConstructor
15+
@Data
16+
public class ModerationRequest {
17+
18+
/**
19+
* The input text to classify.
20+
*/
21+
@NonNull
22+
String input;
23+
24+
/**
25+
* The name of the model to use, defaults to text-moderation-stable.
26+
*/
27+
String model;
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.theokanning.openai.moderation;
2+
3+
import lombok.Data;
4+
5+
import java.util.List;
6+
7+
/**
8+
* An object containing a response from the moderation api
9+
*
10+
* https://beta.openai.com/docs/api-reference/moderations/create
11+
*/
12+
@Data
13+
public class ModerationResult {
14+
/**
15+
* A unique id assigned to this moderation.
16+
*/
17+
String id;
18+
19+
/**
20+
* The GPT-3 model used.
21+
*/
22+
String model;
23+
24+
/**
25+
* A list of moderation scores.
26+
*/
27+
List<Moderation> results;
28+
}

client/src/main/java/com/theokanning/openai/OpenAiApi.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import com.theokanning.openai.finetune.FineTuneEvent;
1616
import com.theokanning.openai.finetune.FineTuneRequest;
1717
import com.theokanning.openai.finetune.FineTuneResult;
18+
import com.theokanning.openai.moderation.ModerationRequest;
19+
import com.theokanning.openai.moderation.ModerationResult;
1820
import com.theokanning.openai.search.SearchRequest;
1921
import com.theokanning.openai.search.SearchResult;
2022
import io.reactivex.Single;
@@ -36,6 +38,9 @@ public interface OpenAiApi {
3638
@POST("/v1/engines/{engine_id}/edits")
3739
Single<EditResult> createEdit(@Path("engine_id") String engineId, @Body EditRequest request);
3840

41+
@POST("/v1/engines/{engine_id}/embeddings")
42+
Single<EmbeddingResult> createEmbeddings(@Path("engine_id") String engineId, @Body EmbeddingRequest request);
43+
3944
@POST("/v1/engines/{engine_id}/search")
4045
Single<OpenAiResponse<SearchResult>> search(@Path("engine_id") String engineId, @Body SearchRequest request);
4146

@@ -79,8 +84,6 @@ public interface OpenAiApi {
7984
@DELETE("/v1/models/{fine_tune_id}")
8085
Single<DeleteResult> deleteFineTune(@Path("fine_tune_id") String fineTuneId);
8186

82-
@POST("/v1/engines/{engine_id}/embeddings")
83-
Single<EmbeddingResult> createEmbeddings(@Path("engine_id") String engineId, @Body EmbeddingRequest request);
84-
85-
87+
@POST("/v1/moderations")
88+
Single<ModerationResult> createModeration(@Body ModerationRequest request);
8689
}

client/src/main/java/com/theokanning/openai/OpenAiService.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import com.theokanning.openai.finetune.FineTuneEvent;
2020
import com.theokanning.openai.finetune.FineTuneRequest;
2121
import com.theokanning.openai.finetune.FineTuneResult;
22+
import com.theokanning.openai.moderation.ModerationRequest;
23+
import com.theokanning.openai.moderation.ModerationResult;
2224
import com.theokanning.openai.search.SearchRequest;
2325
import com.theokanning.openai.search.SearchResult;
2426
import okhttp3.*;
@@ -92,6 +94,10 @@ public EditResult createEdit(String engineId, EditRequest request) {
9294
return api.createEdit(engineId, request).blockingGet();
9395
}
9496

97+
public EmbeddingResult createEmbeddings(String engineId, EmbeddingRequest request) {
98+
return api.createEmbeddings(engineId, request).blockingGet();
99+
}
100+
95101
public List<SearchResult> search(String engineId, SearchRequest request) {
96102
return api.search(engineId, request).blockingGet().data;
97103
}
@@ -153,7 +159,7 @@ public DeleteResult deleteFineTune(String fineTuneId) {
153159
return api.deleteFineTune(fineTuneId).blockingGet();
154160
}
155161

156-
public EmbeddingResult createEmbeddings(String engineId, EmbeddingRequest request) {
157-
return api.createEmbeddings(engineId, request).blockingGet();
162+
public ModerationResult createModeration(ModerationRequest request) {
163+
return api.createModeration(request).blockingGet();
158164
}
159165
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.theokanning.openai;
2+
3+
import com.theokanning.openai.moderation.ModerationRequest;
4+
import com.theokanning.openai.moderation.Moderation;
5+
import org.junit.jupiter.api.Test;
6+
7+
import static org.junit.jupiter.api.Assertions.assertTrue;
8+
9+
10+
public class ModerationTest {
11+
12+
String token = System.getenv("OPENAI_TOKEN");
13+
OpenAiService service = new OpenAiService(token);
14+
15+
@Test
16+
void createModeration() {
17+
ModerationRequest moderationRequest = ModerationRequest.builder()
18+
.input("I want to kill them")
19+
.model("text-moderation-latest")
20+
.build();
21+
22+
Moderation moderationScore = service.createModeration(moderationRequest).getResults().get(0);
23+
24+
assertTrue(moderationScore.isFlagged());
25+
}
26+
}

0 commit comments

Comments
 (0)