Refactor: Remove SensitiveDataMasker and fix PaginationRequestValidator
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 1m55s
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 1m55s
This commit is contained in:
@@ -16,7 +16,6 @@ package io.shinhanlife.dap.mcg.audit;
|
|||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
import io.shinhanlife.dap.mcg.config.McpGatewayProperties;
|
import io.shinhanlife.dap.mcg.config.McpGatewayProperties;
|
||||||
import io.shinhanlife.dap.mcg.guardrail.SensitiveDataMasker;
|
|
||||||
import io.shinhanlife.dap.mcg.security.McpRequestContext;
|
import io.shinhanlife.dap.mcg.security.McpRequestContext;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -32,11 +31,8 @@ import org.springframework.stereotype.Service;
|
|||||||
public class AuditLogService {
|
public class AuditLogService {
|
||||||
private static final Logger audit = LoggerFactory.getLogger("MCP_AUDIT");
|
private static final Logger audit = LoggerFactory.getLogger("MCP_AUDIT");
|
||||||
private final McpGatewayProperties properties;
|
private final McpGatewayProperties properties;
|
||||||
private final SensitiveDataMasker masker;
|
public AuditLogService(McpGatewayProperties properties) {
|
||||||
|
|
||||||
public AuditLogService(McpGatewayProperties properties, SensitiveDataMasker masker) {
|
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.masker = masker;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,7 +43,7 @@ public class AuditLogService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
audit.info("event=tool_started requestId={} agentId={} userId={} clientAddress={} tool={} arguments={}",
|
audit.info("event=tool_started requestId={} agentId={} userId={} clientAddress={} tool={} arguments={}",
|
||||||
context.requestId(), context.agentId(), context.userId(), context.clientAddress(), toolName, masker.mask(arguments));
|
context.requestId(), context.agentId(), context.userId(), context.clientAddress(), toolName, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
package io.shinhanlife.dap.mcg.guardrail;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.dap.mcg.guardrail
|
|
||||||
* @className SensitiveDataMasker
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author 0986406
|
|
||||||
* @create 2026.09.01
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.09.01 0986406 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Audit Log, Redis Trace, Agent 응답 preview에 남으면 안 되는 민감정보를 마스킹합니다.
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class SensitiveDataMasker {
|
|
||||||
private static final Set<String> SENSITIVE_KEYS = Set.of(
|
|
||||||
"password", "passwd", "pwd", "token", "accessToken", "refreshToken", "secret",
|
|
||||||
"ssn", "rrn", "residentNumber", "cardNumber", "accountNumber", "accountNo",
|
|
||||||
"phone", "mobile", "email", "idempotencyKey");
|
|
||||||
private static final Pattern EMAIL = Pattern.compile("([a-zA-Z0-9._%+-]{2})[a-zA-Z0-9._%+-]*(@[a-zA-Z0-9.-]+)");
|
|
||||||
private static final Pattern CARD_OR_ACCOUNT = Pattern.compile("\\b(\\d{4})\\d{4,12}(\\d{2,4})\\b");
|
|
||||||
private final ObjectMapper json;
|
|
||||||
|
|
||||||
public SensitiveDataMasker(ObjectMapper json) {
|
|
||||||
this.json = json;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JsonNode 전체를 재귀적으로 순회하며 민감 key와 민감 패턴을 마스킹합니다.
|
|
||||||
*/
|
|
||||||
public JsonNode mask(JsonNode input) {
|
|
||||||
if (input == null || input.isMissingNode() || input.isNull()) {
|
|
||||||
return json.createObjectNode();
|
|
||||||
}
|
|
||||||
if (input.isArray()) {
|
|
||||||
ArrayNode masked = json.createArrayNode();
|
|
||||||
for (JsonNode item : input) {
|
|
||||||
masked.add(mask(item));
|
|
||||||
}
|
|
||||||
return masked;
|
|
||||||
}
|
|
||||||
if (input.isObject()) {
|
|
||||||
ObjectNode masked = json.createObjectNode();
|
|
||||||
Iterator<Map.Entry<String, JsonNode>> fields = input.fields();
|
|
||||||
while (fields.hasNext()) {
|
|
||||||
Map.Entry<String, JsonNode> entry = fields.next();
|
|
||||||
String key = entry.getKey();
|
|
||||||
JsonNode value = entry.getValue();
|
|
||||||
if (isSensitiveKey(key)) {
|
|
||||||
masked.put(key, "***");
|
|
||||||
} else {
|
|
||||||
masked.set(key, mask(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return masked;
|
|
||||||
}
|
|
||||||
if (input.isTextual()) {
|
|
||||||
return json.valueToTree(maskText(input.asText()));
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isSensitiveKey(String key) {
|
|
||||||
return key != null && SENSITIVE_KEYS.stream().anyMatch(sensitive -> sensitive.equalsIgnoreCase(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String maskText(String value) {
|
|
||||||
if (value == null || value.isBlank()) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
String masked = EMAIL.matcher(value).replaceAll("$1***$2");
|
|
||||||
return CARD_OR_ACCOUNT.matcher(masked).replaceAll("$1********$2");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,7 +16,6 @@ package io.shinhanlife.dap.mcg.redis;
|
|||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
import io.shinhanlife.dap.mcg.config.McpGatewayProperties;
|
import io.shinhanlife.dap.mcg.config.McpGatewayProperties;
|
||||||
import io.shinhanlife.dap.mcg.guardrail.SensitiveDataMasker;
|
|
||||||
import io.shinhanlife.dap.mcg.security.McpRequestContext;
|
import io.shinhanlife.dap.mcg.security.McpRequestContext;
|
||||||
import io.shinhanlife.dap.mcg.dto.ToolMetadata;
|
import io.shinhanlife.dap.mcg.dto.ToolMetadata;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -49,19 +48,16 @@ public class RedisToolTraceService {
|
|||||||
private final ObjectProvider<StringRedisTemplate> redisProvider;
|
private final ObjectProvider<StringRedisTemplate> redisProvider;
|
||||||
private final ObjectMapper json;
|
private final ObjectMapper json;
|
||||||
private final McpMonitorEventService monitorEvents;
|
private final McpMonitorEventService monitorEvents;
|
||||||
private final SensitiveDataMasker masker;
|
|
||||||
private final Map<String, AttemptState> attemptStates = new ConcurrentHashMap<>();
|
private final Map<String, AttemptState> attemptStates = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public RedisToolTraceService(McpGatewayProperties properties,
|
public RedisToolTraceService(McpGatewayProperties properties,
|
||||||
ObjectProvider<StringRedisTemplate> redisProvider,
|
ObjectProvider<StringRedisTemplate> redisProvider,
|
||||||
ObjectMapper json,
|
ObjectMapper json,
|
||||||
McpMonitorEventService monitorEvents,
|
McpMonitorEventService monitorEvents) {
|
||||||
SensitiveDataMasker masker) {
|
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.redisProvider = redisProvider;
|
this.redisProvider = redisProvider;
|
||||||
this.json = json;
|
this.json = json;
|
||||||
this.monitorEvents = monitorEvents;
|
this.monitorEvents = monitorEvents;
|
||||||
this.masker = masker;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,7 +202,7 @@ public class RedisToolTraceService {
|
|||||||
arguments.fieldNames().forEachRemaining(argNames::add);
|
arguments.fieldNames().forEachRemaining(argNames::add);
|
||||||
trace.put("argumentNames", argNames);
|
trace.put("argumentNames", argNames);
|
||||||
|
|
||||||
trace.put("arguments", masker.mask(arguments).toString());
|
trace.put("arguments", arguments.toString());
|
||||||
trace.put("responseSummary", responseSummary(responseText));
|
trace.put("responseSummary", responseSummary(responseText));
|
||||||
trace.put("timestamp", Instant.now().toString());
|
trace.put("timestamp", Instant.now().toString());
|
||||||
return json.writeValueAsString(trace);
|
return json.writeValueAsString(trace);
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import io.shinhanlife.dap.mcg.resilience.RetryPolicy;
|
|||||||
import io.shinhanlife.dap.mcg.resilience.ToolExecutionException;
|
import io.shinhanlife.dap.mcg.resilience.ToolExecutionException;
|
||||||
import io.shinhanlife.dap.mcg.dto.OperationType;
|
import io.shinhanlife.dap.mcg.dto.OperationType;
|
||||||
import io.shinhanlife.dap.mcg.config.McpGatewayProperties;
|
import io.shinhanlife.dap.mcg.config.McpGatewayProperties;
|
||||||
import io.shinhanlife.dap.mcg.guardrail.SensitiveDataMasker;
|
|
||||||
import io.shinhanlife.dap.mcg.guardrail.GuardrailService;
|
import io.shinhanlife.dap.mcg.guardrail.GuardrailService;
|
||||||
import io.shinhanlife.dap.mcg.security.McpRequestContext;
|
import io.shinhanlife.dap.mcg.security.McpRequestContext;
|
||||||
import io.shinhanlife.dap.mcg.security.McpRequestContextResolver;
|
import io.shinhanlife.dap.mcg.security.McpRequestContextResolver;
|
||||||
@@ -58,7 +57,6 @@ public class ExecuteService {
|
|||||||
private final ToolPlanner planner;
|
private final ToolPlanner planner;
|
||||||
private final KillSwitchService killSwitchService;
|
private final KillSwitchService killSwitchService;
|
||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
private final SensitiveDataMasker dataMasker;
|
|
||||||
private final GuardrailService guardrailService;
|
private final GuardrailService guardrailService;
|
||||||
private final McpRequestContextResolver contextResolver;
|
private final McpRequestContextResolver contextResolver;
|
||||||
private final AuditLogService auditLogService;
|
private final AuditLogService auditLogService;
|
||||||
@@ -76,7 +74,6 @@ public class ExecuteService {
|
|||||||
public ExecuteService(ToolPlanner planner,
|
public ExecuteService(ToolPlanner planner,
|
||||||
KillSwitchService killSwitchService,
|
KillSwitchService killSwitchService,
|
||||||
ObjectMapper objectMapper,
|
ObjectMapper objectMapper,
|
||||||
SensitiveDataMasker dataMasker,
|
|
||||||
GuardrailService guardrailService,
|
GuardrailService guardrailService,
|
||||||
McpRequestContextResolver contextResolver,
|
McpRequestContextResolver contextResolver,
|
||||||
AuditLogService auditLogService,
|
AuditLogService auditLogService,
|
||||||
@@ -92,7 +89,6 @@ public class ExecuteService {
|
|||||||
this.planner = planner;
|
this.planner = planner;
|
||||||
this.killSwitchService = killSwitchService;
|
this.killSwitchService = killSwitchService;
|
||||||
this.objectMapper = objectMapper;
|
this.objectMapper = objectMapper;
|
||||||
this.dataMasker = dataMasker;
|
|
||||||
this.guardrailService = guardrailService;
|
this.guardrailService = guardrailService;
|
||||||
this.contextResolver = contextResolver;
|
this.contextResolver = contextResolver;
|
||||||
this.auditLogService = auditLogService;
|
this.auditLogService = auditLogService;
|
||||||
@@ -266,14 +262,14 @@ public class ExecuteService {
|
|||||||
headers.put("trace-id", context.requestId());
|
headers.put("trace-id", context.requestId());
|
||||||
headers.put("request-id", java.util.UUID.randomUUID().toString());
|
headers.put("request-id", java.util.UUID.randomUUID().toString());
|
||||||
|
|
||||||
ObjectNode pageArguments = paginationValidator.normalize(arguments);
|
ObjectNode pageArguments = paginationValidator.normalize(metadata, arguments);
|
||||||
LargeToolResponseService.Collector collector = largeResponses.newCollector(metadata.getName(), context.requestId());
|
LargeToolResponseService.Collector collector = largeResponses.newCollector(metadata.getName(), context.requestId());
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
Map<String, Object> pagePayload = objectMapper.convertValue(pageArguments, Map.class);
|
Map<String, Object> pagePayload = objectMapper.convertValue(pageArguments, Map.class);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
log.info(" [ExecuteService] 요청 페이로드(마스킹 적용): {}", objectMapper.writeValueAsString(dataMasker.mask(objectMapper.valueToTree(pagePayload))));
|
log.info(" [ExecuteService] 요청 페이로드: {}", objectMapper.writeValueAsString(pagePayload));
|
||||||
} catch (Exception ignore) {}
|
} catch (Exception ignore) {}
|
||||||
|
|
||||||
JsonNode data = null;
|
JsonNode data = null;
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import java.util.Iterator;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import io.shinhanlife.dap.mcg.config.AgentResponseBudgetProperties;
|
import io.shinhanlife.dap.mcg.config.AgentResponseBudgetProperties;
|
||||||
import io.shinhanlife.dap.mcg.guardrail.SensitiveDataMasker;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
@@ -30,12 +29,9 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
|||||||
public class AgentResponseBudgetService {
|
public class AgentResponseBudgetService {
|
||||||
private final AgentResponseBudgetProperties properties;
|
private final AgentResponseBudgetProperties properties;
|
||||||
private final ObjectMapper json;
|
private final ObjectMapper json;
|
||||||
private final SensitiveDataMasker masker;
|
public AgentResponseBudgetService(AgentResponseBudgetProperties properties, ObjectMapper json) {
|
||||||
|
|
||||||
public AgentResponseBudgetService(AgentResponseBudgetProperties properties, ObjectMapper json, SensitiveDataMasker masker) {
|
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.json = json;
|
this.json = json;
|
||||||
this.masker = masker;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectNode apply(ObjectNode response) {
|
public ObjectNode apply(ObjectNode response) {
|
||||||
@@ -109,7 +105,7 @@ public class AgentResponseBudgetService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private JsonNode budgetItem(JsonNode item, BudgetStats stats) {
|
private JsonNode budgetItem(JsonNode item, BudgetStats stats) {
|
||||||
JsonNode masked = masker.mask(item);
|
JsonNode masked = item;
|
||||||
if (!masked.isObject()) {
|
if (!masked.isObject()) {
|
||||||
return truncateByBytes(masked, stats);
|
return truncateByBytes(masked, stats);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package io.shinhanlife.dap.mcg.tool.large;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import io.shinhanlife.dap.mcg.config.McpGatewayProperties;
|
import io.shinhanlife.dap.mcg.config.McpGatewayProperties;
|
||||||
import io.shinhanlife.dap.mcg.guardrail.SensitiveDataMasker;
|
|
||||||
import io.shinhanlife.dap.mcg.resilience.FailureType;
|
import io.shinhanlife.dap.mcg.resilience.FailureType;
|
||||||
import io.shinhanlife.dap.mcg.resilience.ToolExecutionException;
|
import io.shinhanlife.dap.mcg.resilience.ToolExecutionException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -34,16 +33,13 @@ import java.time.Instant;
|
|||||||
public class LargeToolResponseService {
|
public class LargeToolResponseService {
|
||||||
private final McpGatewayProperties properties;
|
private final McpGatewayProperties properties;
|
||||||
private final ObjectMapper json;
|
private final ObjectMapper json;
|
||||||
private final SensitiveDataMasker masker;
|
|
||||||
private final AgentResponseBudgetService agentBudget;
|
private final AgentResponseBudgetService agentBudget;
|
||||||
|
|
||||||
public LargeToolResponseService(McpGatewayProperties properties,
|
public LargeToolResponseService(McpGatewayProperties properties,
|
||||||
ObjectMapper json,
|
ObjectMapper json,
|
||||||
SensitiveDataMasker masker,
|
|
||||||
AgentResponseBudgetService agentBudget) {
|
AgentResponseBudgetService agentBudget) {
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.json = json;
|
this.json = json;
|
||||||
this.masker = masker;
|
|
||||||
this.agentBudget = agentBudget;
|
this.agentBudget = agentBudget;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,8 +153,7 @@ public class LargeToolResponseService {
|
|||||||
}
|
}
|
||||||
Page page = pageFrom(data);
|
Page page = pageFrom(data);
|
||||||
if (!page.paginated() && pageCount == 0 && count(page.items()) <= pageSize()) {
|
if (!page.paginated() && pageCount == 0 && count(page.items()) <= pageSize()) {
|
||||||
JsonNode masked = masker.mask(data);
|
normalData = data;
|
||||||
normalData = masked;
|
|
||||||
pageCount = 1;
|
pageCount = 1;
|
||||||
returnedCount = count(page.items());
|
returnedCount = count(page.items());
|
||||||
totalCount = returnedCount;
|
totalCount = returnedCount;
|
||||||
@@ -271,19 +266,18 @@ public class LargeToolResponseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private JsonNode previewItem(JsonNode item) {
|
private JsonNode previewItem(JsonNode item) {
|
||||||
JsonNode masked = masker.mask(item);
|
long itemBytes = jsonBytes(item);
|
||||||
long itemBytes = jsonBytes(masked);
|
|
||||||
if (itemBytes <= properties.largeResponseMaxItemBytes()) {
|
if (itemBytes <= properties.largeResponseMaxItemBytes()) {
|
||||||
return masked;
|
return item;
|
||||||
}
|
}
|
||||||
truncated = true;
|
truncated = true;
|
||||||
ObjectNode preview = json.createObjectNode();
|
ObjectNode preview = json.createObjectNode();
|
||||||
preview.put("truncated", true);
|
preview.put("truncated", true);
|
||||||
preview.put("originalBytes", itemBytes);
|
preview.put("originalBytes", itemBytes);
|
||||||
preview.put("maxItemBytes", properties.largeResponseMaxItemBytes());
|
preview.put("maxItemBytes", properties.largeResponseMaxItemBytes());
|
||||||
if (masked.isObject()) {
|
if (item.isObject()) {
|
||||||
ArrayNode fieldNames = json.createArrayNode();
|
ArrayNode fieldNames = json.createArrayNode();
|
||||||
Iterator<String> fieldNamesIter = masked.fieldNames();
|
Iterator<String> fieldNamesIter = item.fieldNames();
|
||||||
while (fieldNamesIter.hasNext()) {
|
while (fieldNamesIter.hasNext()) {
|
||||||
fieldNames.add(fieldNamesIter.next());
|
fieldNames.add(fieldNamesIter.next());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ package io.shinhanlife.dap.mcg.tool.large;
|
|||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
|
import io.shinhanlife.dap.mcg.dto.ToolMetadata;
|
||||||
import io.shinhanlife.dap.mcg.config.McpGatewayProperties;
|
import io.shinhanlife.dap.mcg.config.McpGatewayProperties;
|
||||||
import io.shinhanlife.dap.mcg.resilience.FailureType;
|
import io.shinhanlife.dap.mcg.resilience.FailureType;
|
||||||
import io.shinhanlife.dap.mcg.resilience.ToolExecutionException;
|
import io.shinhanlife.dap.mcg.resilience.ToolExecutionException;
|
||||||
@@ -40,12 +41,18 @@ public class PaginationRequestValidator {
|
|||||||
/**
|
/**
|
||||||
* pageSize/cursor를 검증한 뒤 Tool 서버에 넘길 안전한 arguments 복사본을 만듭니다.
|
* pageSize/cursor를 검증한 뒤 Tool 서버에 넘길 안전한 arguments 복사본을 만듭니다.
|
||||||
*/
|
*/
|
||||||
public ObjectNode normalize(ObjectNode arguments) {
|
public ObjectNode normalize(ToolMetadata metadata, ObjectNode arguments) {
|
||||||
try {
|
try {
|
||||||
ObjectNode normalized = arguments == null
|
ObjectNode normalized = arguments == null
|
||||||
? json.createObjectNode()
|
? json.createObjectNode()
|
||||||
: (ObjectNode) json.readTree(json.writeValueAsString(arguments));
|
: (ObjectNode) json.readTree(json.writeValueAsString(arguments));
|
||||||
|
|
||||||
|
if (metadata != null && metadata.allowedArguments().contains("pageSize")) {
|
||||||
normalizePageSize(normalized);
|
normalizePageSize(normalized);
|
||||||
|
} else if (normalized.has("pageSize")) {
|
||||||
|
normalizePageSize(normalized);
|
||||||
|
}
|
||||||
|
|
||||||
validateCursor(normalized);
|
validateCursor(normalized);
|
||||||
return normalized;
|
return normalized;
|
||||||
} catch (ToolExecutionException error) {
|
} catch (ToolExecutionException error) {
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ package io.shinhanlife.dap.mcg.tool.result;
|
|||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
import io.shinhanlife.dap.mcg.guardrail.SensitiveDataMasker;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
@@ -34,11 +33,8 @@ public class ToolExecutionResultFormatter {
|
|||||||
private static final int TEXT_PREVIEW_LIMIT = 2_000;
|
private static final int TEXT_PREVIEW_LIMIT = 2_000;
|
||||||
|
|
||||||
private final ObjectMapper json;
|
private final ObjectMapper json;
|
||||||
private final SensitiveDataMasker masker;
|
public ToolExecutionResultFormatter(ObjectMapper json) {
|
||||||
|
|
||||||
public ToolExecutionResultFormatter(ObjectMapper json, SensitiveDataMasker masker) {
|
|
||||||
this.json = json;
|
this.json = json;
|
||||||
this.masker = masker;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,7 +67,7 @@ public class ToolExecutionResultFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ToolExecutionResult fromJson(String toolName, JsonNode parsed, long sizeBytes) {
|
public ToolExecutionResult fromJson(String toolName, JsonNode parsed, long sizeBytes) {
|
||||||
JsonNode masked = masker.mask(parsed);
|
JsonNode masked = parsed;
|
||||||
if (masked.isObject()) {
|
if (masked.isObject()) {
|
||||||
ObjectNode object = (ObjectNode) masked;
|
ObjectNode object = (ObjectNode) masked;
|
||||||
if (object.path("isError").asBoolean(false) || object.has("error") || object.has("failureType")) {
|
if (object.path("isError").asBoolean(false) || object.has("error") || object.has("failureType")) {
|
||||||
|
|||||||
Reference in New Issue
Block a user