mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
fix: strip keyword rows in keyword moderation (#42048)
This commit is contained in:
1 parent
f0d69e7b39
commit
a1bb317892
3 files changed
+32
-10
No files matched your search
@@ -42,8 +42,7 @@ class KeywordsModeration(Moderation):
|
||||
if query:
|
||||
inputs["query__"] = query
|
||||
|
||||
# Filter out empty values
|
||||
keywords_list = [keyword for keyword in self.config["keywords"].split("\n") if keyword]
|
||||
keywords_list = self._keyword_rows(self.config["keywords"])
|
||||
|
||||
flagged = self._is_violated(inputs, keywords_list)
|
||||
|
||||
@@ -59,8 +58,7 @@ class KeywordsModeration(Moderation):
|
||||
raise ValueError("The config is not set.")
|
||||
|
||||
if self.config["outputs_config"]["enabled"]:
|
||||
# Filter out empty values
|
||||
keywords_list = [keyword for keyword in self.config["keywords"].split("\n") if keyword]
|
||||
keywords_list = self._keyword_rows(self.config["keywords"])
|
||||
|
||||
flagged = self._is_violated({"text": text}, keywords_list)
|
||||
preset_response = self.config["outputs_config"]["preset_response"]
|
||||
@@ -69,6 +67,16 @@ class KeywordsModeration(Moderation):
|
||||
flagged=flagged, action=ModerationAction.DIRECT_OUTPUT, preset_response=preset_response
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _keyword_rows(keywords: str) -> list[str]:
|
||||
"""Split the keywords config into stripped, non-empty rows.
|
||||
|
||||
Rows keep surrounding whitespace from pasted configs (for example CRLF
|
||||
line endings) unless stripped: a keyword ending in "\r" never matches
|
||||
real text, and a whitespace-only row matches nearly every message.
|
||||
"""
|
||||
return [row for row in (row.strip() for row in keywords.split("\n")) if row]
|
||||
|
||||
def _is_violated(self, inputs: dict[str, Any], keywords_list: list[str]) -> bool:
|
||||
return any(self._check_keywords_in_value(keywords_list, value) for value in inputs.values())
|
||||
|
||||
|
||||
@@ -127,6 +127,24 @@ class TestKeywordsModeration:
|
||||
with pytest.raises(ValueError, match="inputs_config.preset_response must be less than 100 characters"):
|
||||
KeywordsModeration.validate_config("test-tenant", config)
|
||||
|
||||
def test_moderation_for_inputs_crlf_keywords_match(self, keywords_config: dict[str, Any]):
|
||||
"""Keywords pasted with Windows line endings still match."""
|
||||
keywords_config["keywords"] = "spam\r\nfree money"
|
||||
moderation = KeywordsModeration(app_id="app", tenant_id="tenant", config=keywords_config)
|
||||
|
||||
result = moderation.moderation_for_inputs({}, query="this is spam")
|
||||
|
||||
assert result.flagged is True
|
||||
|
||||
def test_moderation_whitespace_only_keyword_row_is_ignored(self, keywords_config: dict[str, Any]):
|
||||
"""A whitespace-only keyword row must not flag every message."""
|
||||
keywords_config["keywords"] = "spam\n \n "
|
||||
moderation = KeywordsModeration(app_id="app", tenant_id="tenant", config=keywords_config)
|
||||
|
||||
result = moderation.moderation_for_inputs({}, query="a perfectly normal message")
|
||||
|
||||
assert result.flagged is False
|
||||
|
||||
def test_moderation_for_inputs_no_violation(self, keywords_moderation: KeywordsModeration):
|
||||
"""Test input moderation when no keywords are matched."""
|
||||
inputs = {"user_input": "This is a clean message"}
|
||||
|
||||
@@ -621,13 +621,9 @@ class TestEdgeCases:
|
||||
"""Test keyword that is only spaces."""
|
||||
moderation = self._create_moderation(" ")
|
||||
|
||||
# Text without three consecutive spaces should not match
|
||||
result1 = moderation.moderation_for_inputs({"text": "This has spaces"})
|
||||
assert result1.flagged is False
|
||||
result = moderation.moderation_for_inputs({"text": "This has spaces"})
|
||||
|
||||
# Text with three consecutive spaces should match
|
||||
result2 = moderation.moderation_for_inputs({"text": "This has spaces"})
|
||||
assert result2.flagged is True
|
||||
assert result.flagged is False
|
||||
|
||||
def test_config_not_set_error_for_inputs(self):
|
||||
"""Test error when config is not set for input moderation."""
|
||||
|
||||
Reference in new issue
Block a user