Skip to content

Commit 6c42a32

Browse files
marko-kriskovicivicac
authored andcommitted
1345 - rework mask action
1 parent c52ad8f commit 6c42a32

2 files changed

Lines changed: 215 additions & 64 deletions

File tree

  • server/libs/modules/components/ai/universal/universal-text/src

server/libs/modules/components/ai/universal/universal-text/src/main/java/com/bytechef/component/ai/universal/text/action/MaskAction.java

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import static com.bytechef.component.ai.llm.constant.LLMConstants.ROLE;
2424
import static com.bytechef.component.ai.llm.constant.LLMConstants.TEMPERATURE_PROPERTY;
2525
import static com.bytechef.component.ai.universal.text.constant.AiTextConstants.CUSTOM_PATTERNS;
26+
import static com.bytechef.component.ai.universal.text.constant.AiTextConstants.MASK_MAP;
2627
import static com.bytechef.component.ai.universal.text.constant.AiTextConstants.MODEL_NO_OPTIONS_PROPERTY;
2728
import static com.bytechef.component.ai.universal.text.constant.AiTextConstants.MODEL_OPTIONS_PROPERTY;
2829
import static com.bytechef.component.ai.universal.text.constant.AiTextConstants.MODEL_URL_PROPERTY;
@@ -32,10 +33,12 @@
3233
import static com.bytechef.component.ai.universal.text.constant.AiTextConstants.TEXT;
3334
import static com.bytechef.component.definition.ComponentDsl.action;
3435
import static com.bytechef.component.definition.ComponentDsl.array;
36+
import static com.bytechef.component.definition.ComponentDsl.object;
3537
import static com.bytechef.component.definition.ComponentDsl.outputSchema;
3638
import static com.bytechef.component.definition.ComponentDsl.sampleOutput;
3739
import static com.bytechef.component.definition.ComponentDsl.string;
3840

41+
import com.bytechef.component.ai.llm.ChatModel;
3942
import com.bytechef.component.ai.universal.text.action.definition.AiTextActionDefinition;
4043
import com.bytechef.component.ai.universal.text.constant.AiTextConstants;
4144
import com.bytechef.component.definition.ComponentDsl;
@@ -86,8 +89,18 @@ public static AiTextActionDefinition of(
8689
MAX_TOKENS_PROPERTY,
8790
TEMPERATURE_PROPERTY)
8891
.output(
89-
outputSchema(string().description("The text with sensitive content redacted.")),
90-
sampleOutput("Hello, my name is [REDACTED] and my email is [EMAIL].")),
92+
outputSchema(
93+
object()
94+
.properties(
95+
string(TEXT)
96+
.description("The text with sensitive content redacted."),
97+
object(MASK_MAP)
98+
.description("Mapping of mask tokens to their original values.")
99+
.additionalProperties(string()))),
100+
sampleOutput(
101+
Map.of(
102+
TEXT, "Hello, my name is [REDACTED_1] and my email is [EMAIL_1].",
103+
MASK_MAP, Map.of("[REDACTED_1]", "John Doe", "[EMAIL_1]", "john@example.com")))),
91104
provider, new MaskAction(), propertyService);
92105
}
93106

@@ -108,7 +121,9 @@ public Parameters createParameters(Parameters inputParameters) {
108121
Map<String, Object> modelInputParametersMap = new HashMap<>();
109122

110123
String systemPrompt =
111-
"You are a content redaction specialist. Detect and replace sensitive information in the given text with mask tokens. Return only the redacted text with no additional commentary.";
124+
"You are a content redaction specialist. Detect and replace sensitive information in the given text with mask tokens. "
125+
+ "Increment the number suffix (_1, _2, ...) for each unique occurrence of the same type so every masking is unique. "
126+
+ "Respond with a JSON object with two fields: \"text\" (the redacted text) and \"maskMap\" (an object mapping each mask token to the original value it replaced).";
112127

113128
StringBuilder userBuilder = new StringBuilder();
114129

@@ -119,7 +134,7 @@ public Parameters createParameters(Parameters inputParameters) {
119134
List<String> keywords = inputParameters.getList(SENSITIVE_KEYWORDS, String.class, List.of());
120135

121136
if (!keywords.isEmpty()) {
122-
userBuilder.append("- Replace each of the following sensitive keywords with [REDACTED]: ")
137+
userBuilder.append("- Replace each of the following sensitive keywords with [REDACTED_N]: ")
123138
.append(String.join(", ", keywords))
124139
.append("\n");
125140
}
@@ -132,23 +147,46 @@ public Parameters createParameters(Parameters inputParameters) {
132147
.replace("_", " "))
133148
.append(" values with [")
134149
.append(piiType)
135-
.append("]\n");
150+
.append("_N]\n");
136151
}
137152

138153
List<String> customPatterns = inputParameters.getList(CUSTOM_PATTERNS, String.class, List.of());
139154

140155
if (!customPatterns.isEmpty()) {
141-
userBuilder.append("- Replace all matches of the following patterns with [REDACTED]: ")
156+
userBuilder.append("- Replace all matches of the following patterns with [CUSTOM_N]: ")
142157
.append(String.join(", ", customPatterns))
143158
.append("\n");
144159
}
145160

161+
String responseSchema = """
162+
{
163+
"type": "object",
164+
"properties": {
165+
"text": {
166+
"type": "string"
167+
},
168+
"maskMap": {
169+
"type": "object",
170+
"additionalProperties": {
171+
"type": "string"
172+
}
173+
}
174+
},
175+
"required": ["text", "maskMap"]
176+
}
177+
""";
178+
146179
modelInputParametersMap.put(
147180
"messages",
148181
List.of(
149182
Map.of("content", systemPrompt, ROLE, SYSTEM.name()),
150183
Map.of("content", userBuilder.toString(), ROLE, USER.name())));
151184
modelInputParametersMap.put("model", inputParameters.getString(MODEL));
185+
modelInputParametersMap.put(
186+
"response",
187+
Map.of(
188+
"responseFormat", ChatModel.ResponseFormat.JSON,
189+
"responseSchema", responseSchema));
152190

153191
return ParametersFactory.create(modelInputParametersMap);
154192
}

0 commit comments

Comments
 (0)