From 35e78f55e2bd7fd74f4fad46f97206b67ac2b3b9 Mon Sep 17 00:00:00 2001 From: "Mittal, Manan" Date: Tue, 11 Aug 2026 17:30:40 -0400 Subject: [PATCH 1/3] feat: adding in support for subbing fixed text --- .../AggressiveSelfHarmGuardrailEngine.java | 35 +++++++++--- .../PolicyComplianceGuardrailEngine.java | 4 ++ .../pipeline/PipelineInvocationHandler.java | 20 ++++++- .../GenericGuardrailInputReactor.java | 55 ++++++++++++++++++- .../interceptor/PipelineReactorUtils.java | 1 + 5 files changed, 103 insertions(+), 12 deletions(-) diff --git a/src/prerna/engine/impl/guardrail/AggressiveSelfHarmGuardrailEngine.java b/src/prerna/engine/impl/guardrail/AggressiveSelfHarmGuardrailEngine.java index 5cc400aa55..0ae6a88705 100644 --- a/src/prerna/engine/impl/guardrail/AggressiveSelfHarmGuardrailEngine.java +++ b/src/prerna/engine/impl/guardrail/AggressiveSelfHarmGuardrailEngine.java @@ -46,6 +46,7 @@ import prerna.engine.impl.model.message.ResponseMessage; import prerna.om.Insight; import prerna.om.InsightStore; +import prerna.om.ThreadStore; import prerna.sablecc2.om.GenRowStruct; import prerna.sablecc2.om.NounStore; import prerna.sablecc2.om.nounmeta.GuardrailNounMetadata; @@ -63,6 +64,7 @@ * Optional SMSS keys: * */ public class AggressiveSelfHarmGuardrailEngine extends AbstractGuardrailReactorFunctionEngine { @@ -70,8 +72,10 @@ public class AggressiveSelfHarmGuardrailEngine extends AbstractGuardrailReactorF private static final Logger classLogger = LogManager.getLogger(AggressiveSelfHarmGuardrailEngine.class); public static final String MODEL_ENGINE_ID_KEY = "MODEL_ENGINE_ID"; + public static final String SYSTEM_PROMPT_KEY = "SYSTEM_PROMPT"; + public static final String BLOCKED_MESSAGE_KEY = "BLOCKED_MESSAGE"; - private static final String SYSTEM_PROMPT = + private static final String DEFAULT_SYSTEM_PROMPT = "You are a content safety classifier. Your sole task is to detect whether a user message " + "expresses first-person intent to harm themselves or others, suicidal ideation, or aggressive threats.\n\n" + "Respond with ONLY one word:\n" @@ -82,7 +86,13 @@ public class AggressiveSelfHarmGuardrailEngine extends AbstractGuardrailReactorF + "third-party reports, or general medical questions\n\n" + "Do not explain your reasoning. Output only SAFE or UNSAFE."; + private static final String DEFAULT_BLOCKED_MESSAGE = + "I'm sorry, I'm not able to help with that. If you or someone you know is in crisis, " + + "please call or text 988 to reach the Suicide & Crisis Lifeline, or call 911 for immediate emergency assistance."; + private String modelEngineId; + private String systemPrompt; + private String blockedMessage; public AggressiveSelfHarmGuardrailEngine() { this.keysToGet = new String[] { "prompt" }; @@ -98,6 +108,14 @@ public void open(Properties smssProp) throws Exception { } this.modelEngineId = this.modelEngineId.trim(); + String systemPromptProp = this.smssProp.getProperty(SYSTEM_PROMPT_KEY); + this.systemPrompt = (systemPromptProp != null && !systemPromptProp.trim().isEmpty()) + ? systemPromptProp.trim() : DEFAULT_SYSTEM_PROMPT; + + String blockedMessageProp = this.smssProp.getProperty(BLOCKED_MESSAGE_KEY); + this.blockedMessage = (blockedMessageProp != null && !blockedMessageProp.trim().isEmpty()) + ? blockedMessageProp.trim() : DEFAULT_BLOCKED_MESSAGE; + this.functionDescription = "Detects aggressive or self-harm content by asking a configured LLM to classify " + "the prompt as SAFE or UNSAFE."; this.parameters = new ArrayList<>(); @@ -109,6 +127,9 @@ public void open(Properties smssProp) throws Exception { public GuardrailNounMetadata execute(NounStore ns, GenRowStruct curRow) { Map keyValue = organizeKeys(ns, curRow); String prompt = keyValue.get("prompt"); + if (prompt == null) { + throw new IllegalArgumentException("No prompt has been defined"); + } classLogger.info("AggressiveSelfHarmGuardrail: classifying prompt (length={}) via model={}", prompt.length(), this.modelEngineId); @@ -121,13 +142,16 @@ public GuardrailNounMetadata execute(NounStore ns, GenRowStruct curRow) { Insight classificationInsight = new Insight(); InsightStore.getInstance().put(classificationInsight); + String savedJobId = ThreadStore.getJobId(); + ThreadStore.setJobId(null); + String classification; try { Room room = RoomUtils.createRoomIfNotExists(UUID.randomUUID().toString(), classificationInsight, modelEngine, prompt); Map params = new HashMap<>(); params.put("use_history", false); InputMessage msg = InputMessage.builder(room) - .withSystemPrompt(SYSTEM_PROMPT) + .withSystemPrompt(this.systemPrompt) .withText(prompt) .withModelType(modelEngine.getModelType()) .withParamMap(params) @@ -136,6 +160,7 @@ public GuardrailNounMetadata execute(NounStore ns, GenRowStruct curRow) { Object responseObj = response.getModelEngineResponse().toMap().get("response"); classification = responseObj != null ? responseObj.toString().trim() : ""; } finally { + ThreadStore.setJobId(savedJobId); InsightStore.getInstance().remove(classificationInsight.getInsightId()); } @@ -147,11 +172,7 @@ public GuardrailNounMetadata execute(NounStore ns, GenRowStruct curRow) { details.put("classification", classification); details.put("modelEngineId", this.modelEngineId); - String returnPrompt = pass ? prompt - : "Respond only with the following message, word for word: " - + "'I'm sorry, I'm not able to help with that. " - + "If you or someone you know is in crisis, please call or text 988 to reach the Veterans Crisis Line, " - + "or call 911 for immediate emergency assistance.'"; + String returnPrompt = pass ? prompt : this.blockedMessage; return new GuardrailNounMetadata(pass, returnPrompt, details); } diff --git a/src/prerna/engine/impl/guardrail/PolicyComplianceGuardrailEngine.java b/src/prerna/engine/impl/guardrail/PolicyComplianceGuardrailEngine.java index a73f9a7134..1d141d70b6 100644 --- a/src/prerna/engine/impl/guardrail/PolicyComplianceGuardrailEngine.java +++ b/src/prerna/engine/impl/guardrail/PolicyComplianceGuardrailEngine.java @@ -47,6 +47,7 @@ import prerna.engine.impl.model.responses.AbstractModelEngineResponse; import prerna.om.Insight; import prerna.om.InsightStore; +import prerna.om.ThreadStore; import prerna.sablecc2.om.GenRowStruct; import prerna.sablecc2.om.NounStore; import prerna.sablecc2.om.nounmeta.GuardrailNounMetadata; @@ -181,6 +182,8 @@ private String classify(String textToJudge, String policyDescription) throws Exc // Room/model calls require an Insight to be registered, this one is never tied to a real user session. Insight classificationInsight = new Insight(); InsightStore.getInstance().put(classificationInsight); + String savedJobId = ThreadStore.getJobId(); + ThreadStore.setJobId(null); try { Room room = RoomUtils.createRoomIfNotExists(UUID.randomUUID().toString(), classificationInsight, judgeEngine, textToJudge); @@ -196,6 +199,7 @@ private String classify(String textToJudge, String policyDescription) throws Exc Object responseObj = response.getModelEngineResponse().toMap().get("response"); return responseObj != null ? responseObj.toString().trim() : ""; } finally { + ThreadStore.setJobId(savedJobId); InsightStore.getInstance().remove(classificationInsight.getInsightId()); } } diff --git a/src/prerna/engine/impl/pipeline/PipelineInvocationHandler.java b/src/prerna/engine/impl/pipeline/PipelineInvocationHandler.java index fb07d15558..7ffc4ba140 100644 --- a/src/prerna/engine/impl/pipeline/PipelineInvocationHandler.java +++ b/src/prerna/engine/impl/pipeline/PipelineInvocationHandler.java @@ -66,6 +66,8 @@ import prerna.engine.api.IEngine; import prerna.engine.impl.model.Room; import prerna.engine.impl.model.responses.AbstractModelEngineResponse; +import prerna.engine.impl.model.responses.AskModelEngineResponse; +import prerna.engine.impl.model.responses.AskStringModelEngineResponse; import prerna.logging.IgnoreEngineLogging; import prerna.logging.LoggingEngineSerializer; import prerna.logging.LoggingIReactorSerializer; @@ -123,6 +125,7 @@ public class PipelineInvocationHandler implements InvocationHandler { // took private static final String GUARDRAIL_ACTION_MASK = "MASK"; private static final String GUARDRAIL_ACTION_BLOCK = "BLOCK"; + private static final String GUARDRAIL_ACTION_RESPOND = "RESPOND"; private final ZoneId UTC_ZONE_ID = ZoneId.of("UTC"); private final Map pipelinesMap = new HashMap<>(); @@ -309,9 +312,12 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl .get(PipelineReactorUtils.INTERIM_RESULT); boolean pass = (boolean) resultMap.get(PipelineReactorUtils.PASS); boolean masked = Boolean.TRUE.equals(resultMap.get(PipelineReactorUtils.MASKED)); + String cannedResponse = (String) resultMap.get(PipelineReactorUtils.SHORT_CIRCUIT_RESPONSE); // MASK when the guardrail neutralized content, BLOCK when it stopped the - // request, null when it ran clean - queryable via the GUARDRAIL_ACTION column - String guardrailAction = masked ? GUARDRAIL_ACTION_MASK : (!pass ? GUARDRAIL_ACTION_BLOCK : null); + // request, RESPOND when it supplied the answer itself, null when it ran clean + // - queryable via the GUARDRAIL_ACTION column + String guardrailAction = cannedResponse != null ? GUARDRAIL_ACTION_RESPOND + : masked ? GUARDRAIL_ACTION_MASK : (!pass ? GUARDRAIL_ACTION_BLOCK : null); String request = null; String response = null; @@ -328,6 +334,16 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl logEngineCall(engineSpecificLogger, start, end, pass, request, response, reactor.getClass().getSimpleName(), null, null, null, guardrailAction); + if (cannedResponse != null) { + if (!AskModelEngineResponse.class.isAssignableFrom(method.getReturnType())) { + throw new SemossPixelException( + "Unable to process this request due to content policy (guardrail input exception)"); + } + classLogger.warn("Guardrail {} short-circuited the model call with a canned response", + reactor.getClass().getSimpleName()); + return new AskStringModelEngineResponse(cannedResponse, 0, 0); + } + if (!pass) { throw new SemossPixelException( "Unable to process this request due to content policy (guardrail input exception)"); diff --git a/src/prerna/reactor/interceptor/GenericGuardrailInputReactor.java b/src/prerna/reactor/interceptor/GenericGuardrailInputReactor.java index bfc24de8b9..930771edab 100644 --- a/src/prerna/reactor/interceptor/GenericGuardrailInputReactor.java +++ b/src/prerna/reactor/interceptor/GenericGuardrailInputReactor.java @@ -36,6 +36,10 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + import prerna.engine.api.IGuardrailReactorFunctionEngine; import prerna.reactor.AbstractReactor; import prerna.sablecc2.om.GenRowStruct; @@ -168,7 +172,7 @@ public NounMetadata execute() { // text - not the original - flows downstream to the model. boolean masked = false; Boolean maskOnGuardrailFailure = helper.getConfigParameter("maskOnGuardrailFailure", Boolean.class); - if (maskOnGuardrailFailure != null && maskOnGuardrailFailure && !output.isPass()) { + if (Boolean.TRUE.equals(maskOnGuardrailFailure) && !output.isPass()) { String maskTargetParam = helper.getConfigParameter("maskTargetParam", String.class); if (maskTargetParam == null || maskTargetParam.isEmpty()) { maskTargetParam = DEFAULT_MASK_TARGET_PARAM; @@ -179,6 +183,7 @@ public NounMetadata execute() { String maskedPrompt = output.getReturnPrompt(); if (mappedArg instanceof String && maskedPrompt != null) { processedArguments.put((String) mappedArg, maskedPrompt); + patchMessageJsonCurrentTurn(processedArguments, maskedPrompt); masked = true; } else { // cannot safely write the masked value back (e.g. a combined multi-arg @@ -191,7 +196,17 @@ public NounMetadata execute() { } } - Map resultMap = createInterimResult(output, this.getClass().getName(), masked); + // When configured to respond (rather than mask or block), hand the guardrail's + // message back as the model's answer. The real model call is skipped entirely, + // so no version of the prompt reaches the provider. + String cannedResponse = null; + Boolean respondWithGuardrailMessage = helper.getConfigParameter("respondWithGuardrailMessage", Boolean.class); + if (Boolean.TRUE.equals(respondWithGuardrailMessage) && !output.isPass()) { + cannedResponse = output.getReturnPrompt(); + } + + Map resultMap = createInterimResult(output, this.getClass().getName(), masked, + cannedResponse); // Update the processedArguments with the interim result processedArguments.put(PipelineReactorUtils.INTERIM_RESULT, resultMap); @@ -205,14 +220,48 @@ public NounMetadata execute() { * @param interceptorName * @return */ + @SuppressWarnings("unchecked") + private void patchMessageJsonCurrentTurn(Map processedArguments, String maskedPrompt) { + for (Object val : processedArguments.values()) { + if (!(val instanceof Map)) { + continue; + } + Map asMap = (Map) val; + Object mj = asMap.get("message_json"); + if (!(mj instanceof String)) { + continue; + } + try { + JsonArray messages = JsonParser.parseString((String) mj).getAsJsonArray(); + if (messages.isEmpty()) { + continue; + } + JsonObject lastMessage = messages.get(messages.size() - 1).getAsJsonObject(); + JsonArray parts = lastMessage.getAsJsonArray("parts"); + if (parts != null && !parts.isEmpty()) { + JsonObject firstPart = parts.get(0).getAsJsonObject(); + firstPart.addProperty("text", maskedPrompt); + firstPart.addProperty("uiText", maskedPrompt); + asMap.put("message_json", messages.toString()); + } + } catch (Exception e) { + classLogger.warn("Unable to patch message_json with masked prompt; current-turn text in history " + + "may still be unmasked: {}", e.getMessage()); + } + } + } + private Map createInterimResult(GuardrailNounMetadata results, String interceptorName, - boolean masked) { + boolean masked, String cannedResponse) { Map resultMap = new HashMap<>(); resultMap.put(PipelineReactorUtils.INTERCEPTOR, interceptorName); // when we masked the input we neutralized the failure, so let it pass downstream resultMap.put(PipelineReactorUtils.PASS, masked || results.isPass()); resultMap.put(PipelineReactorUtils.PASS_DETAILS, results.getValue()); resultMap.put(PipelineReactorUtils.MASKED, masked); + if (cannedResponse != null) { + resultMap.put(PipelineReactorUtils.SHORT_CIRCUIT_RESPONSE, cannedResponse); + } return resultMap; } diff --git a/src/prerna/reactor/interceptor/PipelineReactorUtils.java b/src/prerna/reactor/interceptor/PipelineReactorUtils.java index a947bae9b9..d34e6fed40 100644 --- a/src/prerna/reactor/interceptor/PipelineReactorUtils.java +++ b/src/prerna/reactor/interceptor/PipelineReactorUtils.java @@ -48,6 +48,7 @@ public final class PipelineReactorUtils { public static final String PASS = "pass"; public static final String PASS_DETAILS = "passDetails"; public static final String MASKED = "masked"; + public static final String SHORT_CIRCUIT_RESPONSE = "shortCircuitResponse"; private PipelineReactorUtils() { // private constructor to prevent instantiation From c62f12eed622378c5ffdc155042ed745c2d45592 Mon Sep 17 00:00:00 2001 From: "Mittal, Manan" Date: Tue, 11 Aug 2026 17:50:18 -0400 Subject: [PATCH 2/3] fix: small bugs --- .../GenericGuardrailInputReactor.java | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/prerna/reactor/interceptor/GenericGuardrailInputReactor.java b/src/prerna/reactor/interceptor/GenericGuardrailInputReactor.java index 930771edab..67ec0dc943 100644 --- a/src/prerna/reactor/interceptor/GenericGuardrailInputReactor.java +++ b/src/prerna/reactor/interceptor/GenericGuardrailInputReactor.java @@ -37,10 +37,12 @@ import org.apache.logging.log4j.Logger; import com.google.gson.JsonArray; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import prerna.engine.api.IGuardrailReactorFunctionEngine; +import prerna.engine.impl.model.message.MessagePartType; import prerna.reactor.AbstractReactor; import prerna.sablecc2.om.GenRowStruct; import prerna.sablecc2.om.NounStore; @@ -181,17 +183,17 @@ public NounMetadata execute() { // method argument name (e.g. "arg0"); that argument is what we overwrite Object mappedArg = inputMapping.get(maskTargetParam); String maskedPrompt = output.getReturnPrompt(); - if (mappedArg instanceof String && maskedPrompt != null) { + if (mappedArg instanceof String && maskedPrompt != null + && patchMessageJsonCurrentTurn(processedArguments, maskedPrompt)) { processedArguments.put((String) mappedArg, maskedPrompt); - patchMessageJsonCurrentTurn(processedArguments, maskedPrompt); masked = true; } else { - // cannot safely write the masked value back (e.g. a combined multi-arg - // mapping) - leave pass as-is so the request is blocked rather than - // leaking unmasked content downstream + // cannot safely rewrite the outbound payload (combined multi-arg mapping, + // or the current-turn text isn't in message_json yet, e.g. the full_prompt + // path) - block rather than leak unmasked content downstream classLogger.warn( - "maskOnGuardrailFailure is enabled but mask target '{}' is not mapped to a single argument; " - + "blocking instead of masking.", + "maskOnGuardrailFailure is enabled but the outbound payload could not be rewritten for " + + "mask target '{}'; blocking instead of masking.", maskTargetParam); } } @@ -221,7 +223,8 @@ public NounMetadata execute() { * @return */ @SuppressWarnings("unchecked") - private void patchMessageJsonCurrentTurn(Map processedArguments, String maskedPrompt) { + private boolean patchMessageJsonCurrentTurn(Map processedArguments, String maskedPrompt) { + boolean patched = false; for (Object val : processedArguments.values()) { if (!(val instanceof Map)) { continue; @@ -238,17 +241,28 @@ private void patchMessageJsonCurrentTurn(Map processedArguments, } JsonObject lastMessage = messages.get(messages.size() - 1).getAsJsonObject(); JsonArray parts = lastMessage.getAsJsonArray("parts"); - if (parts != null && !parts.isEmpty()) { - JsonObject firstPart = parts.get(0).getAsJsonObject(); - firstPart.addProperty("text", maskedPrompt); - firstPart.addProperty("uiText", maskedPrompt); + if (parts == null) { + continue; + } + boolean patchedThis = false; + for (JsonElement partEle : parts) { + JsonObject part = partEle.getAsJsonObject(); + JsonElement type = part.get("type"); + if (type != null && MessagePartType.TEXT.name().equals(type.getAsString())) { + part.addProperty("text", maskedPrompt); + part.addProperty("uiText", maskedPrompt); + patchedThis = true; + } + } + if (patchedThis) { asMap.put("message_json", messages.toString()); + patched = true; } } catch (Exception e) { - classLogger.warn("Unable to patch message_json with masked prompt; current-turn text in history " - + "may still be unmasked: {}", e.getMessage()); + classLogger.warn("Unable to patch message_json with masked prompt: {}", e.getMessage()); } } + return patched; } private Map createInterimResult(GuardrailNounMetadata results, String interceptorName, From ab8642a0a938e3b0a4967d8329b5e609d7747947 Mon Sep 17 00:00:00 2001 From: manamittal Date: Tue, 11 Aug 2026 18:03:20 -0400 Subject: [PATCH 3/3] refactor: splitting branch for mask fix --- .../GenericGuardrailInputReactor.java | 64 ++----------------- 1 file changed, 7 insertions(+), 57 deletions(-) diff --git a/src/prerna/reactor/interceptor/GenericGuardrailInputReactor.java b/src/prerna/reactor/interceptor/GenericGuardrailInputReactor.java index 67ec0dc943..09a00b863c 100644 --- a/src/prerna/reactor/interceptor/GenericGuardrailInputReactor.java +++ b/src/prerna/reactor/interceptor/GenericGuardrailInputReactor.java @@ -36,13 +36,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; - import prerna.engine.api.IGuardrailReactorFunctionEngine; -import prerna.engine.impl.model.message.MessagePartType; import prerna.reactor.AbstractReactor; import prerna.sablecc2.om.GenRowStruct; import prerna.sablecc2.om.NounStore; @@ -174,7 +168,7 @@ public NounMetadata execute() { // text - not the original - flows downstream to the model. boolean masked = false; Boolean maskOnGuardrailFailure = helper.getConfigParameter("maskOnGuardrailFailure", Boolean.class); - if (Boolean.TRUE.equals(maskOnGuardrailFailure) && !output.isPass()) { + if (maskOnGuardrailFailure != null && maskOnGuardrailFailure && !output.isPass()) { String maskTargetParam = helper.getConfigParameter("maskTargetParam", String.class); if (maskTargetParam == null || maskTargetParam.isEmpty()) { maskTargetParam = DEFAULT_MASK_TARGET_PARAM; @@ -183,17 +177,16 @@ public NounMetadata execute() { // method argument name (e.g. "arg0"); that argument is what we overwrite Object mappedArg = inputMapping.get(maskTargetParam); String maskedPrompt = output.getReturnPrompt(); - if (mappedArg instanceof String && maskedPrompt != null - && patchMessageJsonCurrentTurn(processedArguments, maskedPrompt)) { + if (mappedArg instanceof String && maskedPrompt != null) { processedArguments.put((String) mappedArg, maskedPrompt); masked = true; } else { - // cannot safely rewrite the outbound payload (combined multi-arg mapping, - // or the current-turn text isn't in message_json yet, e.g. the full_prompt - // path) - block rather than leak unmasked content downstream + // cannot safely write the masked value back (e.g. a combined multi-arg + // mapping) - leave pass as-is so the request is blocked rather than + // leaking unmasked content downstream classLogger.warn( - "maskOnGuardrailFailure is enabled but the outbound payload could not be rewritten for " - + "mask target '{}'; blocking instead of masking.", + "maskOnGuardrailFailure is enabled but mask target '{}' is not mapped to a single argument; " + + "blocking instead of masking.", maskTargetParam); } } @@ -222,49 +215,6 @@ && patchMessageJsonCurrentTurn(processedArguments, maskedPrompt)) { * @param interceptorName * @return */ - @SuppressWarnings("unchecked") - private boolean patchMessageJsonCurrentTurn(Map processedArguments, String maskedPrompt) { - boolean patched = false; - for (Object val : processedArguments.values()) { - if (!(val instanceof Map)) { - continue; - } - Map asMap = (Map) val; - Object mj = asMap.get("message_json"); - if (!(mj instanceof String)) { - continue; - } - try { - JsonArray messages = JsonParser.parseString((String) mj).getAsJsonArray(); - if (messages.isEmpty()) { - continue; - } - JsonObject lastMessage = messages.get(messages.size() - 1).getAsJsonObject(); - JsonArray parts = lastMessage.getAsJsonArray("parts"); - if (parts == null) { - continue; - } - boolean patchedThis = false; - for (JsonElement partEle : parts) { - JsonObject part = partEle.getAsJsonObject(); - JsonElement type = part.get("type"); - if (type != null && MessagePartType.TEXT.name().equals(type.getAsString())) { - part.addProperty("text", maskedPrompt); - part.addProperty("uiText", maskedPrompt); - patchedThis = true; - } - } - if (patchedThis) { - asMap.put("message_json", messages.toString()); - patched = true; - } - } catch (Exception e) { - classLogger.warn("Unable to patch message_json with masked prompt: {}", e.getMessage()); - } - } - return patched; - } - private Map createInterimResult(GuardrailNounMetadata results, String interceptorName, boolean masked, String cannedResponse) { Map resultMap = new HashMap<>();