package com.vincent.rsf.server.ai.tool;
|
|
import com.vincent.rsf.framework.exception.CoolException;
|
import org.springframework.util.StringUtils;
|
|
import java.util.ArrayList;
|
import java.util.List;
|
|
public final class BuiltinToolGovernanceSupport {
|
|
private BuiltinToolGovernanceSupport() {
|
}
|
|
/**
|
* 把工具入参里的 limit 统一收敛到安全范围内。
|
* 所有内置只读工具都通过该方法限制返回规模,避免模型一次查询过多数据。
|
*/
|
public static int normalizeLimit(Integer limit, int defaultValue, int maxValue) {
|
if (limit == null) {
|
return defaultValue;
|
}
|
if (limit < 1 || limit > maxValue) {
|
throw new CoolException("limit 必须在 1 到 " + maxValue + " 之间");
|
}
|
return limit;
|
}
|
|
/**
|
* 要求多个过滤条件里至少有一个有效值。
|
* 这是防止 AI 工具被模型当成“全表扫描接口”使用的第一道保护。
|
*/
|
public static void requireAnyFilter(String message, String... values) {
|
if (values == null || values.length == 0) {
|
throw new CoolException(message);
|
}
|
for (String value : values) {
|
if (StringUtils.hasText(value)) {
|
return;
|
}
|
}
|
throw new CoolException(message);
|
}
|
|
/**
|
* 清洗单个文本型查询参数,并限制最大长度。
|
* 这里只做轻量治理,不做模糊兜底或自动纠错,非法输入直接拒绝。
|
*/
|
public static String sanitizeQueryText(String value, String fieldLabel, int maxLength) {
|
if (!StringUtils.hasText(value)) {
|
return null;
|
}
|
String normalized = value.trim();
|
if (normalized.length() > maxLength) {
|
throw new CoolException(fieldLabel + "长度不能超过 " + maxLength);
|
}
|
return normalized;
|
}
|
|
/**
|
* 清洗字符串数组型参数,常用于站点类型、状态列表等批量过滤条件。
|
* 返回结果会自动剔除空值,但如果最终为空仍然视为非法请求。
|
*/
|
public static List<String> sanitizeStringList(List<String> values, String fieldLabel, int maxSize, int maxItemLength) {
|
if (values == null || values.isEmpty()) {
|
throw new CoolException(fieldLabel + "不能为空");
|
}
|
if (values.size() > maxSize) {
|
throw new CoolException(fieldLabel + "数量不能超过 " + maxSize);
|
}
|
List<String> result = new ArrayList<>();
|
for (String value : values) {
|
String normalized = sanitizeQueryText(value, fieldLabel + "项", maxItemLength);
|
if (!StringUtils.hasText(normalized)) {
|
continue;
|
}
|
result.add(normalized);
|
}
|
if (result.isEmpty()) {
|
throw new CoolException(fieldLabel + "不能为空");
|
}
|
return result;
|
}
|
}
|