Skip to content

Commit 8a73d0a

Browse files
fix: change default re_flags to NOFLAG in RegexDetector
1 parent e5c4eb3 commit 8a73d0a

File tree

3 files changed

+10
-74
lines changed

3 files changed

+10
-74
lines changed

garak/detectors/function.py

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -42,46 +42,11 @@ class FunctionDetector(Detector):
4242
"""Detector that calls user-provided function for custom detection logic.
4343
4444
Inspired by generators.function. The user specifies a function in the format
45-
'module#function', and it's called with each output string.
45+
'module#function', and it's called with each output string. Additional kwargs
46+
can be passed to the function.
4647
47-
The function must have signature: function(output_text: str) -> float
48+
The function must have signature: function(output_text: str, **kwargs) -> float
4849
where return value is 0.0 (safe) to 1.0 (detected).
49-
50-
Configuration (via --detector_options or --detector_option_file):
51-
{
52-
"function": {
53-
"FunctionDetector": {
54-
"function_name": "mymodule#myfunction",
55-
"kwargs": { # Optional: additional args passed to function
56-
"threshold": 0.5,
57-
"custom_param": "value"
58-
}
59-
}
60-
}
61-
}
62-
63-
Examples:
64-
# In mydetectors.py:
65-
def check_length(output_text, min_length=100):
66-
return 1.0 if len(output_text) > min_length else 0.0
67-
68-
# CLI:
69-
--detector_options '{"function": {"FunctionDetector": {
70-
"function_name": "mydetectors#check_length",
71-
"kwargs": {"min_length": 150}
72-
}}}'
73-
74-
# In mydetectors.py:
75-
def check_pii(output_text):
76-
import re
77-
has_ssn = bool(re.search(r'\\d{3}-\\d{2}-\\d{4}', output_text))
78-
has_email = bool(re.search(r'\\S+@\\S+', output_text))
79-
return 1.0 if (has_ssn or has_email) else 0.0
80-
81-
# CLI:
82-
--detector_options '{"function": {"FunctionDetector": {
83-
"function_name": "mydetectors#check_pii"
84-
}}}'
8550
"""
8651

8752
DEFAULT_PARAMS = Detector.DEFAULT_PARAMS | {

garak/detectors/regex.py

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Regex-based detector for pattern matching in model outputs.
22
33
This module provides a configurable regex detector that allows users to
4-
detect specific patterns in LLM outputs without writing custom detector classes.
4+
detect specific patterns in LLM outputs.
55
66
CLI Examples:
77
# Using --config with a consolidated YAML config file (recommended)
@@ -19,7 +19,7 @@
1919
# - "api.?key"
2020
# - "sk-[A-Za-z0-9]{32,}"
2121
# match_type: "any"
22-
# re_flags: ["IGNORECASE"]
22+
# re_flags: ["IGNORECASE"] # list of re.RegexFlag names (NOFLAG by default)
2323
2424
# Or using inline --detector_options
2525
garak --detectors regex.RegexDetector \\
@@ -42,17 +42,6 @@ class RegexDetector(Detector):
4242
Useful for detecting specific strings,
4343
code patterns, credentials, or any text that matches regex patterns.
4444
45-
Configuration:
46-
{
47-
"regex": {
48-
"RegexDetector": {
49-
"patterns": ["pattern1", "pattern2", ...],
50-
"match_type": "any", # or "all"
51-
"re_flags": ["IGNORECASE"] # list of re.RegexFlag names
52-
}
53-
}
54-
}
55-
5645
Available re_flags (from re.RegexFlag):
5746
- NOFLAG: No special flags (default behavior)
5847
- IGNORECASE (or I): Case-insensitive matching
@@ -61,31 +50,13 @@ class RegexDetector(Detector):
6150
- VERBOSE (or X): Allow comments and whitespace in pattern
6251
- ASCII (or A): ASCII-only matching for \\w, \\b, etc.
6352
- LOCALE (or L): Locale-dependent matching (discouraged)
64-
65-
Examples:
66-
# Detect credentials (case-insensitive)
67-
--detector_options '{"regex": {"RegexDetector": {
68-
"patterns": ["api.?key", "sk-[A-Za-z0-9]{32,}"]
69-
}}}'
70-
71-
# Detect multiline patterns (e.g., code blocks)
72-
--detector_options '{"regex": {"RegexDetector": {
73-
"patterns": ["^import\\s+os", "^sudo"],
74-
"re_flags": ["IGNORECASE", "MULTILINE"]
75-
}}}'
76-
77-
# Case-sensitive exact matching
78-
--detector_options '{"regex": {"RegexDetector": {
79-
"patterns": ["SECRET_KEY", "API_TOKEN"],
80-
"re_flags": ["NOFLAG"]
81-
}}}'
8253
"""
8354
lang_spec = "*"
8455

8556
DEFAULT_PARAMS = Detector.DEFAULT_PARAMS | {
8657
"patterns": [], # users must provide patterns
8758
"match_type": "any", # "any" or "all"
88-
"re_flags": ["IGNORECASE"], # list of re.RegexFlag names to combine
59+
"re_flags": ["NOFLAG"], # list of re.RegexFlag names to combine
8960
}
9061

9162
active = False

tests/detectors/test_detectors_regex.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -321,14 +321,14 @@ def test_invalid_flag_skipped_with_warning(self):
321321
results = detector.detect(attempt)
322322
assert results[0] == 1.0 # Case-insensitive match works
323323

324-
def test_default_flags_ignorecase(self):
325-
"""Test that default re_flags includes IGNORECASE for backward compatibility"""
324+
def test_default_flags_noflag(self):
325+
"""Test that default re_flags includes NOFLAG"""
326326
config = {
327327
'detectors': {
328328
'regex': {
329329
'RegexDetector': {
330330
'patterns': ['PASSWORD']
331-
# No re_flags specified - should default to IGNORECASE
331+
# No re_flags specified - should default to NOFLAG
332332
}
333333
}
334334
}
@@ -340,7 +340,7 @@ def test_default_flags_ignorecase(self):
340340
attempt.outputs = [garak.attempt.Message("password")] # lowercase
341341

342342
results = detector.detect(attempt)
343-
assert results[0] == 1.0 # Default is case-insensitive
343+
assert results[0] == 0.0 # Default is NOFLAG (case-sensitive)
344344

345345
def test_invalid_match_type_defaults_to_any(self):
346346
"""Test that invalid match_type defaults to 'any' with warning (no error)"""

0 commit comments

Comments
 (0)