Skip to content

Commit a15242f

Browse files
author
BitsAdmin
committed
Merge branch 'llmshield/dev-online-1.7.0' into 'integration_2025-12-05_1090279190786'
feat: [development task] llm shield (1902662) See merge request iaasng/volcengine-java-sdk!790
2 parents f16e66a + 607942a commit a15242f

File tree

6 files changed

+163
-12
lines changed

6 files changed

+163
-12
lines changed

volcengine-java-sdk-llmshield/src/main/java/com/volcengine/llmshield/ApiClient.java

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,33 @@
11
package com.volcengine.llmshield;
22

33
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import org.apache.http.HttpHost;
45
import org.apache.http.HttpResponse;
56
import org.apache.http.client.HttpClient;
67
import org.apache.http.client.methods.HttpPost;
78
import org.apache.http.client.utils.URIBuilder;
89
import org.apache.http.entity.StringEntity;
10+
import org.apache.http.impl.client.CloseableHttpClient;
911
import org.apache.http.impl.client.HttpClientBuilder;
1012
import org.apache.http.util.EntityUtils;
1113

1214
import java.io.IOException;
15+
import java.net.MalformedURLException;
1316
import java.net.URI;
14-
import java.net.URISyntaxException;
15-
import java.util.HashMap;
16-
import java.util.Map;
17+
import java.net.URL;
1718
import java.util.concurrent.TimeUnit;
1819

19-
2020
// 客户端类
2121

2222
public class ApiClient {
2323
private final String CONTENT_TYPE_HEADER = "application/json";
24-
25-
2624
private final String url;
2725
private final String ak;
2826
private final String sk;
2927
private final String region;
30-
private HttpClient httpClient;
28+
private CloseableHttpClient httpClient;
3129

32-
private ApiClient(String url, String ak,String sk,String region, long timeout) {
30+
private ApiClient(String url, String ak, String sk, String region, long timeout) {
3331
this.url = url;
3432
this.ak = ak;
3533
this.sk = sk;
@@ -39,6 +37,36 @@ private ApiClient(String url, String ak,String sk,String region, long timeout)
3937
.build();
4038
}
4139

40+
private ApiClient(String url, String ak, String sk, String region, long timeout, String proxy, int connMax) throws MalformedURLException {
41+
this.url = url;
42+
this.ak = ak;
43+
this.sk = sk;
44+
this.region = region;
45+
46+
HttpClientBuilder builder = HttpClientBuilder.create().setConnectionTimeToLive(timeout, TimeUnit.MILLISECONDS);
47+
if (proxy != null && !proxy.isEmpty()) {
48+
try {
49+
URL purl = new URL(proxy);
50+
String p_protocol = purl.getProtocol(); // 协议(http/https 等)
51+
String p_host = purl.getHost(); // 主机名(域名或 IP)
52+
int p_port = purl.getPort(); // 显式指定的端口号
53+
if (p_port < 0) {
54+
p_port = purl.getDefaultPort();// 协议默认端口
55+
}
56+
HttpHost httpsProxy = new HttpHost(p_host, p_port, p_protocol);
57+
builder.setProxy(httpsProxy);
58+
} catch (MalformedURLException e) {
59+
throw new IllegalArgumentException("Invalid Proxy Info:" + proxy, e);
60+
}
61+
}
62+
63+
if (connMax > 0) {
64+
builder.setMaxConnTotal(connMax).setMaxConnPerRoute(connMax);
65+
}
66+
67+
this.httpClient = builder.build();
68+
}
69+
4270
/**
4371
* 创建新的客户端实例
4472
*
@@ -49,10 +77,51 @@ private ApiClient(String url, String ak,String sk,String region, long timeout)
4977
* @param timeout 连接超时时间(毫秒)
5078
* @return 客户端实例
5179
*/
52-
public static ApiClient New(String url, String ak,String sk , String region, long timeout) {
80+
public static ApiClient New(String url, String ak, String sk, String region, long timeout) {
5381
return new ApiClient(url, ak,sk,region, timeout);
5482
}
5583

84+
/**
85+
* 创建新的客户端实例
86+
*
87+
* @param url API 请求的基础 URL
88+
* @param ak 访问密钥
89+
* @param sk 密钥
90+
* @param region 区域
91+
* @param proxy 代理地址
92+
* @param timeout 连接超时时间(毫秒)
93+
* @return 客户端实例
94+
*/
95+
public static ApiClient New(String url, String ak, String sk, String region, long timeout, String proxy, int connMax) throws MalformedURLException {
96+
return new ApiClient(url, ak, sk, region, timeout, proxy, connMax);
97+
}
98+
99+
/**
100+
* 关闭客户端
101+
*
102+
* @return 无
103+
*/
104+
public void Close() throws IOException {
105+
try {
106+
this.httpClient.close();
107+
} catch (IOException e) {
108+
throw new RuntimeException(e);
109+
}
110+
}
111+
112+
/**
113+
* 设置环境
114+
* @param IsDev 是否为dev环境
115+
* @return 无
116+
*/
117+
public void SetServiceDev(boolean IsDev) {
118+
Sign.setServiceDev(IsDev);
119+
}
120+
121+
public String GetServiceCode() {
122+
return Sign.getServiceCode();
123+
}
124+
56125
/**
57126
* 多模态、多轮对话审核
58127
*

volcengine-java-sdk-llmshield/src/main/java/com/volcengine/llmshield/ContentTypeV2.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ public enum ContentTypeV2 {
55
TEXT(1), // 文本
66
AUDIO(2), // 音频
77
IMAGE(3), // 图片
8-
VIDEO(4); // 视频
8+
VIDEO(4), // 视频
9+
FILE(5); // 文件
910

1011
private final long value;
1112

volcengine-java-sdk-llmshield/src/main/java/com/volcengine/llmshield/MessageV2.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import com.fasterxml.jackson.annotation.JsonProperty;
44

5+
import java.util.ArrayList;
6+
import java.util.List;
7+
58
// 消息结构
69
public class MessageV2 {
710
@JsonProperty("Role")
@@ -13,13 +16,23 @@ public class MessageV2 {
1316
@JsonProperty("ContentType")
1417
private ContentTypeV2 contentType; // 内容类型
1518

19+
@JsonProperty("MultiPart")
20+
private List<MultiPart> multiPart; // 多模态内容
21+
1622
// 深拷贝构造方法
1723
public MessageV2(MessageV2 other) {
1824
// String是不可变类型,直接赋值即可
1925
this.role = other.role;
2026
this.content = other.content;
21-
2227
this.contentType = other.contentType;
28+
29+
// List<multiPart>:新建List并对每个元素深拷贝
30+
if (other.multiPart != null) {
31+
this.multiPart = new ArrayList<>();
32+
for (MultiPart contPart : other.multiPart) {
33+
this.multiPart.add(new MultiPart(contPart)); // 假设MultiPart有深拷贝构造方法
34+
}
35+
}
2336
}
2437

2538
// 无参构造方法(保留,用于JSON反序列化等场景)
@@ -48,4 +61,17 @@ public ContentTypeV2 getContentType() {
4861
public void setContentType(ContentTypeV2 contentType) {
4962
this.contentType = contentType;
5063
}
64+
65+
public List<MultiPart> getMultiPart() { return multiPart; }
66+
67+
public void setMultiPart(List<MultiPart> multiPart) { this.multiPart = multiPart; }
68+
69+
// 追加单条历史消息
70+
public MessageV2 appendMultiPart(MultiPart contPart) {
71+
if (this.multiPart == null) {
72+
this.multiPart = new ArrayList<>();
73+
}
74+
this.multiPart.add(contPart);
75+
return this; // 支持链式调用
76+
}
5177
}

volcengine-java-sdk-llmshield/src/main/java/com/volcengine/llmshield/ModerateV2Result.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ public class ModerateV2Result {
1616
@JsonProperty("PermitInfo")
1717
private PermitInfoV2 permitInfo; // 放行信息
1818

19+
@JsonProperty("ContentInfo")
20+
private String contentInfo; // 提交内容信息
21+
1922
@JsonProperty("Degraded")
2023
private boolean degraded; // 是否降级
2124

@@ -58,6 +61,10 @@ public void setPermitInfo(PermitInfoV2 permitInfo) {
5861
this.permitInfo = permitInfo;
5962
}
6063

64+
public String getContentInfo() { return contentInfo; }
65+
66+
public void setContentInfo(String contentInfo) { this.contentInfo = contentInfo;}
67+
6168
public boolean isDegraded() {
6269
return degraded;
6370
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.volcengine.llmshield;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
public class MultiPart {
6+
@JsonProperty("Content")
7+
private String content; // 内容文本或链接
8+
9+
@JsonProperty("ContentType")
10+
private ContentTypeV2 contentType; // 内容类型
11+
12+
// 深拷贝构造方法
13+
public MultiPart(MultiPart other) {
14+
// String是不可变类型,直接赋值即可
15+
this.content = other.content;
16+
this.contentType = other.contentType;
17+
}
18+
19+
// 无参构造方法(保留,用于JSON反序列化等场景)
20+
public MultiPart() {}
21+
public String getContent() { return content; }
22+
23+
public void setContent(String content) { this.content = content; }
24+
25+
public ContentTypeV2 getContentType() { return contentType; }
26+
27+
public void setContentType(ContentTypeV2 contentType) { this.contentType = contentType; }
28+
}

volcengine-java-sdk-llmshield/src/main/java/com/volcengine/llmshield/Sign.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,19 @@
3434
*/
3535
public class Sign {
3636
// 常量定义
37+
private static final String SERVICE_CODE_DEV = "llmshield_dev";
38+
private static final String SERVICE_CODE_ONLINE = "llmshield";
39+
3740
private static final String VERSION = "2025-08-31";
38-
private static final String SERVICE = "llmshield";
3941
private static final BitSet URLENCODER = new BitSet(256);
4042
private static final String CONST_ENCODE = "0123456789ABCDEF";
4143
public static final Charset UTF_8 = StandardCharsets.UTF_8;
4244
// 默认 Content-Type(可根据实际需求调整,若请求体为 JSON 可改为 application/json)
4345
private static final String DEFAULT_CONTENT_TYPE = "application/json";
4446

47+
private static boolean isModified = false; //记录是否已修改过
48+
private static String SERVICE = SERVICE_CODE_ONLINE;
49+
4550
// 静态初始化 URL 编码允许的字符(复用原逻辑)
4651
static {
4752
int i;
@@ -62,6 +67,21 @@ public class Sign {
6267
URLENCODER.set('~');
6368
}
6469

70+
public static synchronized void setServiceDev(boolean IsDev) {
71+
if (!isModified) {
72+
if (IsDev) {
73+
SERVICE = SERVICE_CODE_DEV;
74+
} else {
75+
SERVICE = SERVICE_CODE_ONLINE;
76+
}
77+
isModified = true;
78+
}
79+
}
80+
81+
public static String getServiceCode() {
82+
return SERVICE;
83+
}
84+
6585
/**
6686
* 核心加签方法:为 HttpPost 请求添加火山引擎 API 签名
6787
*

0 commit comments

Comments
 (0)