Skip to content

Commit e5660e3

Browse files
authored
feat: support moderation api (#55)
1 parent 8f5f986 commit e5660e3

File tree

10 files changed

+543
-0
lines changed

10 files changed

+543
-0
lines changed

core/src/main/java/ai/z/openapi/AbstractAiClient.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import ai.z.openapi.service.assistant.AssistantServiceImpl;
2626
import ai.z.openapi.service.voiceclone.VoiceCloneService;
2727
import ai.z.openapi.service.voiceclone.VoiceCloneServiceImpl;
28+
import ai.z.openapi.service.moderations.ModerationService;
29+
import ai.z.openapi.service.moderations.ModerationServiceImpl;
2830
import ai.z.openapi.core.config.ZaiConfig;
2931
import ai.z.openapi.core.model.BiFlowableClientResponse;
3032
import ai.z.openapi.core.model.ClientRequest;
@@ -104,6 +106,9 @@ public abstract class AbstractAiClient extends AbstractClientBaseService {
104106
/** Voice clone service for voice cloning operations */
105107
private VoiceCloneService voiceCloneService;
106108

109+
/** Moderation service for content safety detection */
110+
private ModerationService moderationService;
111+
107112
/**
108113
* Constructs a new AbstractAiClient with the specified configuration.
109114
* @param config the configuration object containing API keys, timeouts, and other
@@ -256,6 +261,18 @@ public synchronized VoiceCloneService voiceClone() {
256261
return voiceCloneService;
257262
}
258263

264+
/**
265+
* Returns the moderation service for content safety detection. This service handles
266+
* content moderation for text, image, video, and audio inputs.
267+
* @return the ModerationService instance (lazily initialized)
268+
*/
269+
public synchronized ModerationService moderations() {
270+
if (moderationService == null) {
271+
this.moderationService = new ModerationServiceImpl(this);
272+
}
273+
return moderationService;
274+
}
275+
259276
// ==================== Utility Methods ====================
260277

261278
/**
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package ai.z.openapi.api.moderations;
2+
3+
import ai.z.openapi.service.moderations.ModerationCreateParams;
4+
import ai.z.openapi.service.moderations.ModerationResult;
5+
import io.reactivex.rxjava3.core.Single;
6+
import retrofit2.http.Body;
7+
import retrofit2.http.POST;
8+
9+
/**
10+
* Moderation API for content safety detection Provides content moderation capabilities
11+
* for text, image, audio, and video formats Accurately identifies risky content including
12+
* adult content, violence, illegal content, etc. Returns structured moderation results
13+
* including content type, risk type, and specific risk segments
14+
*/
15+
public interface ModerationApi {
16+
17+
/**
18+
* Create a content moderation request for safety detection Analyzes content for
19+
* potential risks including adult content, violence, illegal activities Supports
20+
* multiple content types: text strings, images, audio, and video files Returns
21+
* detailed risk assessment with structured results and specific risk segments
22+
* @param request Moderation parameters including content to analyze (text string or
23+
* multimedia object) Text: maximum 2000 characters Images: less than 10M, minimum
24+
* resolution 20x20, maximum 6000x6000 Video: recommended duration 30 seconds Audio:
25+
* recommended duration 60 seconds
26+
* @return Moderation response with risk level (PASS/REVIEW/REJECT), content type,
27+
* risk types, and processing time information
28+
*/
29+
@POST("moderations")
30+
Single<ModerationResult> createModeration(@Body ModerationCreateParams request);
31+
32+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package ai.z.openapi.service.moderations;
2+
3+
import ai.z.openapi.core.model.ClientRequest;
4+
import ai.z.openapi.service.CommonRequest;
5+
import lombok.*;
6+
import lombok.experimental.SuperBuilder;
7+
8+
import java.util.List;
9+
10+
/**
11+
* Parameters for creating a moderation request to check content safety.
12+
*/
13+
@EqualsAndHashCode(callSuper = true)
14+
@SuperBuilder
15+
@NoArgsConstructor
16+
@AllArgsConstructor
17+
@Data
18+
public class ModerationCreateParams extends CommonRequest implements ClientRequest<ModerationCreateParams> {
19+
20+
/**
21+
* The model to use for moderation. Currently, supports "moderation".
22+
*/
23+
private String model;
24+
25+
/**
26+
* The input content to moderate. Can be text, image, video, or audio.
27+
*/
28+
private List<ModerationInput> input;
29+
30+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package ai.z.openapi.service.moderations;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.Data;
7+
import lombok.NoArgsConstructor;
8+
9+
/**
10+
* Base class for moderation input content
11+
*/
12+
@Data
13+
@Builder
14+
@NoArgsConstructor
15+
@AllArgsConstructor
16+
public class ModerationInput {
17+
18+
/**
19+
* Type of content being moderated Possible values: "text", "image_url", "video_url",
20+
* "audio_url"
21+
*/
22+
private String type;
23+
24+
/**
25+
* Text content for text moderation
26+
*/
27+
private String text;
28+
29+
/**
30+
* Image URL configuration for image moderation
31+
*/
32+
@JsonProperty("image_url")
33+
private MediaUrl imageUrl;
34+
35+
/**
36+
* Video URL configuration for video moderation
37+
*/
38+
@JsonProperty("video_url")
39+
private MediaUrl videoUrl;
40+
41+
/**
42+
* Audio URL configuration for audio moderation
43+
*/
44+
@JsonProperty("audio_url")
45+
private MediaUrl audioUrl;
46+
47+
/**
48+
* Helper method to create text input
49+
*/
50+
public static ModerationInput text(String text) {
51+
return ModerationInput.builder().type("text").text(text).build();
52+
}
53+
54+
/**
55+
* Helper method to create image input
56+
*/
57+
public static ModerationInput image(String url) {
58+
return ModerationInput.builder().type("image_url").imageUrl(MediaUrl.builder().url(url).build()).build();
59+
}
60+
61+
/**
62+
* Helper method to create video input
63+
*/
64+
public static ModerationInput video(String url) {
65+
return ModerationInput.builder().type("video_url").videoUrl(MediaUrl.builder().url(url).build()).build();
66+
}
67+
68+
/**
69+
* Helper method to create audio input
70+
*/
71+
public static ModerationInput audio(String url) {
72+
return ModerationInput.builder().type("audio_url").audioUrl(MediaUrl.builder().url(url).build()).build();
73+
}
74+
75+
/**
76+
* Media URL configuration
77+
*/
78+
@Data
79+
@Builder
80+
@NoArgsConstructor
81+
@AllArgsConstructor
82+
public static class MediaUrl {
83+
84+
/**
85+
* URL of the media file
86+
*/
87+
private String url;
88+
89+
}
90+
91+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package ai.z.openapi.service.moderations;
2+
3+
import ai.z.openapi.core.model.ClientResponse;
4+
import ai.z.openapi.service.model.ChatError;
5+
import lombok.Data;
6+
7+
/**
8+
* Response wrapper for moderation API calls. Contains the result of content moderation
9+
* operations along with status information.
10+
*/
11+
@Data
12+
public class ModerationResponse implements ClientResponse<ModerationResult> {
13+
14+
/**
15+
* Response status code.
16+
*/
17+
private int code;
18+
19+
/**
20+
* Response message.
21+
*/
22+
private String msg;
23+
24+
/**
25+
* Indicates whether the request was successful.
26+
*/
27+
private boolean success;
28+
29+
/**
30+
* The moderation result data.
31+
*/
32+
private ModerationResult data;
33+
34+
/**
35+
* Error information if the request failed.
36+
*/
37+
private ChatError error;
38+
39+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package ai.z.openapi.service.moderations;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.Data;
7+
import lombok.NoArgsConstructor;
8+
9+
import java.util.List;
10+
11+
/**
12+
* Result data from the moderation API containing safety analysis results.
13+
*/
14+
@Data
15+
@Builder
16+
@NoArgsConstructor
17+
@AllArgsConstructor
18+
public class ModerationResult {
19+
20+
/**
21+
* Task id.
22+
*/
23+
private String id;
24+
25+
/**
26+
* Unique request identifier for tracking.
27+
*/
28+
@JsonProperty("request_id")
29+
private String requestId;
30+
31+
/**
32+
* Request time in milliseconds.
33+
*/
34+
private Long created;
35+
36+
/**
37+
* List of moderation results for each input item.
38+
*/
39+
@JsonProperty("result_list")
40+
private List<ModerationItem> resultList;
41+
42+
/**
43+
* Token usage information for the request.
44+
*/
45+
private ModerationUsage usage;
46+
47+
/**
48+
* Individual moderation result for a single input item.
49+
*/
50+
@Data
51+
@Builder
52+
@NoArgsConstructor
53+
@AllArgsConstructor
54+
public static class ModerationItem {
55+
56+
/**
57+
* Type of content being moderated (text, image, video, audio).
58+
*/
59+
@JsonProperty("content_type")
60+
private String contentType;
61+
62+
/**
63+
* Risk level assessment: "PASS", "REVIEW", "REJECT".
64+
*/
65+
@JsonProperty("risk_level")
66+
private String riskLevel;
67+
68+
@JsonProperty("risk_type")
69+
private List<String> riskType;
70+
71+
/**
72+
* Check if the content is flagged as unsafe.
73+
* @return true if risk level is REVIEW or REJECT
74+
*/
75+
public boolean isFlagged() {
76+
return "REVIEW".equalsIgnoreCase(riskLevel) || "REJECT".equalsIgnoreCase(riskLevel);
77+
}
78+
79+
/**
80+
* Check if the content is safe.
81+
* @return true if risk level is low
82+
*/
83+
public boolean isSafe() {
84+
return "PASS".equalsIgnoreCase(riskLevel);
85+
}
86+
87+
}
88+
89+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package ai.z.openapi.service.moderations;
2+
3+
/**
4+
* Moderation service for content safety detection Provides content moderation
5+
* capabilities for text, image, audio, and video formats Accurately identifies risky
6+
* content including adult content, violence, illegal content, etc. Returns structured
7+
* moderation results including content type, risk type, and specific risk segments
8+
*/
9+
public interface ModerationService {
10+
11+
/**
12+
* Create a content moderation request for safety detection Analyzes content for
13+
* potential risks including adult content, violence, illegal activities Supports
14+
* multiple content types: text strings, images, audio, and video files Returns
15+
* detailed risk assessment with structured results and specific risk segments
16+
* @param request Moderation parameters including content to analyze (text string or
17+
* multimedia object) Text: maximum 2000 characters Images: less than 10M, minimum
18+
* resolution 20x20, maximum 6000x6000 Video: recommended duration 30 seconds Audio:
19+
* recommended duration 60 seconds
20+
* @return Moderation response with risk level (PASS/REVIEW/REJECT), content type,
21+
* risk types, and processing time information
22+
*/
23+
ModerationResponse createModeration(ModerationCreateParams request);
24+
25+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package ai.z.openapi.service.moderations;
2+
3+
import ai.z.openapi.AbstractAiClient;
4+
import ai.z.openapi.api.moderations.ModerationApi;
5+
import ai.z.openapi.utils.RequestSupplier;
6+
7+
/**
8+
* Implementation of ModerationService
9+
*/
10+
public class ModerationServiceImpl implements ModerationService {
11+
12+
private final AbstractAiClient zAiClient;
13+
14+
private final ModerationApi moderationApi;
15+
16+
public ModerationServiceImpl(AbstractAiClient zAiClient) {
17+
this.zAiClient = zAiClient;
18+
this.moderationApi = zAiClient.retrofit().create(ModerationApi.class);
19+
}
20+
21+
@Override
22+
public ModerationResponse createModeration(ModerationCreateParams request) {
23+
RequestSupplier<ModerationCreateParams, ModerationResult> supplier = moderationApi::createModeration;
24+
return this.zAiClient.executeRequest(request, supplier, ModerationResponse.class);
25+
}
26+
27+
}

0 commit comments

Comments
 (0)