* upgrade libraries
Browse files* ensure all new features of llm guard are supported
- .gitignore +1 -0
- app.py +2 -29
- output.py +121 -37
- prompt.py +82 -33
- requirements.txt +4 -4
.gitignore
CHANGED
@@ -1 +1,2 @@
|
|
1 |
venv
|
|
|
|
1 |
venv
|
2 |
+
.idea
|
app.py
CHANGED
@@ -5,31 +5,12 @@ import traceback
|
|
5 |
import pandas as pd
|
6 |
import streamlit as st
|
7 |
from llm_guard.vault import Vault
|
8 |
-
from streamlit.components.v1 import html
|
9 |
|
10 |
from output import init_settings as init_output_settings
|
11 |
from output import scan as scan_output
|
12 |
from prompt import init_settings as init_prompt_settings
|
13 |
from prompt import scan as scan_prompt
|
14 |
|
15 |
-
|
16 |
-
def add_google_analytics(ga4_id):
|
17 |
-
"""
|
18 |
-
Add Google Analytics 4 to a Streamlit app
|
19 |
-
"""
|
20 |
-
ga_code = f"""
|
21 |
-
<script async src="https://www.googletagmanager.com/gtag/js?id={ga4_id}"></script>
|
22 |
-
<script>
|
23 |
-
window.dataLayer = window.dataLayer || [];
|
24 |
-
function gtag(){{dataLayer.push(arguments);}}
|
25 |
-
gtag('js', new Date());
|
26 |
-
gtag('config', '{ga4_id}');
|
27 |
-
</script>
|
28 |
-
"""
|
29 |
-
|
30 |
-
html(ga_code)
|
31 |
-
|
32 |
-
|
33 |
PROMPT = "prompt"
|
34 |
OUTPUT = "output"
|
35 |
vault = Vault()
|
@@ -39,7 +20,7 @@ st.set_page_config(
|
|
39 |
layout="wide",
|
40 |
initial_sidebar_state="expanded",
|
41 |
menu_items={
|
42 |
-
"About": "https://
|
43 |
},
|
44 |
)
|
45 |
|
@@ -66,21 +47,13 @@ if scanner_type == PROMPT:
|
|
66 |
elif scanner_type == OUTPUT:
|
67 |
enabled_scanners, settings = init_output_settings()
|
68 |
|
69 |
-
add_google_analytics("G-0HBVNHEZBW")
|
70 |
-
|
71 |
# Main pannel
|
72 |
st.subheader("Guard Prompt" if scanner_type == PROMPT else "Guard Output")
|
73 |
with st.expander("About", expanded=False):
|
74 |
st.info(
|
75 |
"""LLM-Guard is a comprehensive tool designed to fortify the security of Large Language Models (LLMs).
|
76 |
\n\n[Code](https://github.com/laiyer-ai/llm-guard) |
|
77 |
-
[Documentation](https://
|
78 |
-
)
|
79 |
-
|
80 |
-
st.markdown(
|
81 |
-
"[![Pypi Downloads](https://img.shields.io/pypi/dm/llm-guard.svg)](https://img.shields.io/pypi/dm/llm-guard.svg)" # noqa
|
82 |
-
"[![MIT license](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT)"
|
83 |
-
"![GitHub Repo stars](https://img.shields.io/github/stars/laiyer-ai/llm-guard?style=social)"
|
84 |
)
|
85 |
|
86 |
analyzer_load_state = st.info("Starting LLM Guard...")
|
|
|
5 |
import pandas as pd
|
6 |
import streamlit as st
|
7 |
from llm_guard.vault import Vault
|
|
|
8 |
|
9 |
from output import init_settings as init_output_settings
|
10 |
from output import scan as scan_output
|
11 |
from prompt import init_settings as init_prompt_settings
|
12 |
from prompt import scan as scan_prompt
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
PROMPT = "prompt"
|
15 |
OUTPUT = "output"
|
16 |
vault = Vault()
|
|
|
20 |
layout="wide",
|
21 |
initial_sidebar_state="expanded",
|
22 |
menu_items={
|
23 |
+
"About": "https://llm-guard.com/",
|
24 |
},
|
25 |
)
|
26 |
|
|
|
47 |
elif scanner_type == OUTPUT:
|
48 |
enabled_scanners, settings = init_output_settings()
|
49 |
|
|
|
|
|
50 |
# Main pannel
|
51 |
st.subheader("Guard Prompt" if scanner_type == PROMPT else "Guard Output")
|
52 |
with st.expander("About", expanded=False):
|
53 |
st.info(
|
54 |
"""LLM-Guard is a comprehensive tool designed to fortify the security of Large Language Models (LLMs).
|
55 |
\n\n[Code](https://github.com/laiyer-ai/llm-guard) |
|
56 |
+
[Documentation](https://llm-guard.com/)"""
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
)
|
58 |
|
59 |
analyzer_load_state = st.info("Starting LLM Guard...")
|
output.py
CHANGED
@@ -6,8 +6,11 @@ from typing import Dict, List
|
|
6 |
import streamlit as st
|
7 |
from llm_guard.input_scanners.anonymize import default_entity_types
|
8 |
from llm_guard.output_scanners import get_scanner_by_name
|
|
|
9 |
from llm_guard.output_scanners.deanonymize import MatchingStrategy as DeanonymizeMatchingStrategy
|
|
|
10 |
from llm_guard.output_scanners.relevance import all_models as relevance_models
|
|
|
11 |
from llm_guard.vault import Vault
|
12 |
from streamlit_tags import st_tags
|
13 |
|
@@ -16,6 +19,7 @@ logger = logging.getLogger("llm-guard-playground")
|
|
16 |
|
17 |
def init_settings() -> (List, Dict):
|
18 |
all_scanners = [
|
|
|
19 |
"BanSubstrings",
|
20 |
"BanTopics",
|
21 |
"Bias",
|
@@ -26,12 +30,14 @@ def init_settings() -> (List, Dict):
|
|
26 |
"LanguageSame",
|
27 |
"MaliciousURLs",
|
28 |
"NoRefusal",
|
|
|
29 |
"FactualConsistency",
|
30 |
"Regex",
|
31 |
"Relevance",
|
32 |
"Sensitive",
|
33 |
"Sentiment",
|
34 |
"Toxicity",
|
|
|
35 |
]
|
36 |
|
37 |
st_enabled_scanners = st.sidebar.multiselect(
|
@@ -43,6 +49,36 @@ def init_settings() -> (List, Dict):
|
|
43 |
|
44 |
settings = {}
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
if "BanSubstrings" in st_enabled_scanners:
|
47 |
st_bs_expander = st.sidebar.expander(
|
48 |
"Ban Substrings",
|
@@ -56,10 +92,14 @@ def init_settings() -> (List, Dict):
|
|
56 |
height=200,
|
57 |
).split("\n")
|
58 |
|
59 |
-
st_bs_match_type = st.selectbox(
|
60 |
-
|
61 |
-
|
62 |
-
|
|
|
|
|
|
|
|
|
63 |
|
64 |
settings["BanSubstrings"] = {
|
65 |
"substrings": st_bs_substrings,
|
@@ -112,7 +152,14 @@ def init_settings() -> (List, Dict):
|
|
112 |
key="bias_threshold",
|
113 |
)
|
114 |
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
|
117 |
if "Code" in st_enabled_scanners:
|
118 |
st_cd_expander = st.sidebar.expander(
|
@@ -127,16 +174,12 @@ def init_settings() -> (List, Dict):
|
|
127 |
default=["python"],
|
128 |
)
|
129 |
|
130 |
-
|
131 |
-
|
132 |
-
allowed_languages = None
|
133 |
-
denied_languages = None
|
134 |
-
if st_cd_mode == "allowed":
|
135 |
-
allowed_languages = st_cd_languages
|
136 |
-
elif st_cd_mode == "denied":
|
137 |
-
denied_languages = st_cd_languages
|
138 |
|
139 |
-
settings["Code"] = {
|
|
|
|
|
|
|
140 |
|
141 |
if "Deanonymize" in st_enabled_scanners:
|
142 |
st_de_expander = st.sidebar.expander(
|
@@ -170,7 +213,9 @@ def init_settings() -> (List, Dict):
|
|
170 |
help="The minimum number of JSON elements that should be present",
|
171 |
)
|
172 |
|
173 |
-
st_json_repair = st.checkbox(
|
|
|
|
|
174 |
|
175 |
settings["JSON"] = {
|
176 |
"required_elements": st_json_required_elements,
|
@@ -211,8 +256,13 @@ def init_settings() -> (List, Dict):
|
|
211 |
default=["en"],
|
212 |
)
|
213 |
|
|
|
|
|
|
|
|
|
214 |
settings["Language"] = {
|
215 |
"valid_languages": st_lan_valid_language,
|
|
|
216 |
}
|
217 |
|
218 |
if "MaliciousURLs" in st_enabled_scanners:
|
@@ -251,6 +301,31 @@ def init_settings() -> (List, Dict):
|
|
251 |
|
252 |
settings["NoRefusal"] = {"threshold": st_no_ref_threshold}
|
253 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
254 |
if "FactualConsistency" in st_enabled_scanners:
|
255 |
st_fc_expander = st.sidebar.expander(
|
256 |
"FactualConsistency",
|
@@ -282,28 +357,19 @@ def init_settings() -> (List, Dict):
|
|
282 |
height=200,
|
283 |
).split("\n")
|
284 |
|
285 |
-
|
286 |
-
"Match type",
|
287 |
-
["good", "bad"],
|
288 |
-
index=1,
|
289 |
-
help="good: allow only good patterns, bad: ban bad patterns",
|
290 |
-
)
|
291 |
|
292 |
-
|
293 |
-
"Redact",
|
|
|
|
|
|
|
294 |
)
|
295 |
|
296 |
-
good_patterns = None
|
297 |
-
bad_patterns = None
|
298 |
-
if st_regex_type == "good":
|
299 |
-
good_patterns = st_regex_patterns
|
300 |
-
elif st_regex_type == "bad":
|
301 |
-
bad_patterns = st_regex_patterns
|
302 |
-
|
303 |
settings["Regex"] = {
|
304 |
-
"
|
305 |
-
"
|
306 |
-
"redact":
|
307 |
}
|
308 |
|
309 |
if "Relevance" in st_enabled_scanners:
|
@@ -389,15 +455,33 @@ def init_settings() -> (List, Dict):
|
|
389 |
with st_tox_expander:
|
390 |
st_tox_threshold = st.slider(
|
391 |
label="Threshold",
|
392 |
-
value=0.
|
393 |
-
min_value
|
394 |
max_value=1.0,
|
395 |
step=0.05,
|
396 |
key="toxicity_threshold",
|
397 |
-
help="A negative value (closer to 0 as the label output) indicates toxicity in the text, while a positive logit (closer to 1 as the label output) suggests non-toxicity.",
|
398 |
)
|
399 |
|
400 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
401 |
|
402 |
return st_enabled_scanners, settings
|
403 |
|
|
|
6 |
import streamlit as st
|
7 |
from llm_guard.input_scanners.anonymize import default_entity_types
|
8 |
from llm_guard.output_scanners import get_scanner_by_name
|
9 |
+
from llm_guard.output_scanners.bias import MatchType as BiasMatchType
|
10 |
from llm_guard.output_scanners.deanonymize import MatchingStrategy as DeanonymizeMatchingStrategy
|
11 |
+
from llm_guard.output_scanners.language import MatchType as LanguageMatchType
|
12 |
from llm_guard.output_scanners.relevance import all_models as relevance_models
|
13 |
+
from llm_guard.output_scanners.toxicity import MatchType as ToxicityMatchType
|
14 |
from llm_guard.vault import Vault
|
15 |
from streamlit_tags import st_tags
|
16 |
|
|
|
19 |
|
20 |
def init_settings() -> (List, Dict):
|
21 |
all_scanners = [
|
22 |
+
"BanCompetitors",
|
23 |
"BanSubstrings",
|
24 |
"BanTopics",
|
25 |
"Bias",
|
|
|
30 |
"LanguageSame",
|
31 |
"MaliciousURLs",
|
32 |
"NoRefusal",
|
33 |
+
"ReadingTime",
|
34 |
"FactualConsistency",
|
35 |
"Regex",
|
36 |
"Relevance",
|
37 |
"Sensitive",
|
38 |
"Sentiment",
|
39 |
"Toxicity",
|
40 |
+
"URLReachability",
|
41 |
]
|
42 |
|
43 |
st_enabled_scanners = st.sidebar.multiselect(
|
|
|
49 |
|
50 |
settings = {}
|
51 |
|
52 |
+
if "BanCompetitors" in st_enabled_scanners:
|
53 |
+
st_bc_expander = st.sidebar.expander(
|
54 |
+
"Ban Competitors",
|
55 |
+
expanded=False,
|
56 |
+
)
|
57 |
+
|
58 |
+
with st_bc_expander:
|
59 |
+
st_bc_competitors = st_tags(
|
60 |
+
label="List of competitors",
|
61 |
+
text="Type and press enter",
|
62 |
+
value=["openai", "anthropic", "deepmind", "google"],
|
63 |
+
suggestions=[],
|
64 |
+
maxtags=30,
|
65 |
+
key="bc_competitors",
|
66 |
+
)
|
67 |
+
|
68 |
+
st_bc_threshold = st.slider(
|
69 |
+
label="Threshold",
|
70 |
+
value=0.5,
|
71 |
+
min_value=0.0,
|
72 |
+
max_value=1.0,
|
73 |
+
step=0.05,
|
74 |
+
key="ban_competitors_threshold",
|
75 |
+
)
|
76 |
+
|
77 |
+
settings["BanCompetitors"] = {
|
78 |
+
"competitors": st_bc_competitors,
|
79 |
+
"threshold": st_bc_threshold,
|
80 |
+
}
|
81 |
+
|
82 |
if "BanSubstrings" in st_enabled_scanners:
|
83 |
st_bs_expander = st.sidebar.expander(
|
84 |
"Ban Substrings",
|
|
|
92 |
height=200,
|
93 |
).split("\n")
|
94 |
|
95 |
+
st_bs_match_type = st.selectbox(
|
96 |
+
"Match type", ["str", "word"], index=0, key="bs_match_type"
|
97 |
+
)
|
98 |
+
st_bs_case_sensitive = st.checkbox(
|
99 |
+
"Case sensitive", value=False, key="bs_case_sensitive"
|
100 |
+
)
|
101 |
+
st_bs_redact = st.checkbox("Redact", value=False, key="bs_redact")
|
102 |
+
st_bs_contains_all = st.checkbox("Contains all", value=False, key="bs_contains_all")
|
103 |
|
104 |
settings["BanSubstrings"] = {
|
105 |
"substrings": st_bs_substrings,
|
|
|
152 |
key="bias_threshold",
|
153 |
)
|
154 |
|
155 |
+
st_bias_match_type = st.selectbox(
|
156 |
+
"Match type", [e.value for e in BiasMatchType], index=1, key="bias_match_type"
|
157 |
+
)
|
158 |
+
|
159 |
+
settings["Bias"] = {
|
160 |
+
"threshold": st_bias_threshold,
|
161 |
+
"match_type": BiasMatchType(st_bias_match_type),
|
162 |
+
}
|
163 |
|
164 |
if "Code" in st_enabled_scanners:
|
165 |
st_cd_expander = st.sidebar.expander(
|
|
|
174 |
default=["python"],
|
175 |
)
|
176 |
|
177 |
+
st_cd_is_blocked = st.checkbox("Is blocked", value=False, key="cd_is_blocked")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
|
179 |
+
settings["Code"] = {
|
180 |
+
"languages": st_cd_languages,
|
181 |
+
"is_blocked": st_cd_is_blocked,
|
182 |
+
}
|
183 |
|
184 |
if "Deanonymize" in st_enabled_scanners:
|
185 |
st_de_expander = st.sidebar.expander(
|
|
|
213 |
help="The minimum number of JSON elements that should be present",
|
214 |
)
|
215 |
|
216 |
+
st_json_repair = st.checkbox(
|
217 |
+
"Repair", value=False, help="Attempt to repair the JSON", key="json_repair"
|
218 |
+
)
|
219 |
|
220 |
settings["JSON"] = {
|
221 |
"required_elements": st_json_required_elements,
|
|
|
256 |
default=["en"],
|
257 |
)
|
258 |
|
259 |
+
st_lan_match_type = st.selectbox(
|
260 |
+
"Match type", [e.value for e in LanguageMatchType], index=1, key="lan_match_type"
|
261 |
+
)
|
262 |
+
|
263 |
settings["Language"] = {
|
264 |
"valid_languages": st_lan_valid_language,
|
265 |
+
"match_type": LanguageMatchType(st_lan_match_type),
|
266 |
}
|
267 |
|
268 |
if "MaliciousURLs" in st_enabled_scanners:
|
|
|
301 |
|
302 |
settings["NoRefusal"] = {"threshold": st_no_ref_threshold}
|
303 |
|
304 |
+
if "ReadingTime" in st_enabled_scanners:
|
305 |
+
st_rt_expander = st.sidebar.expander(
|
306 |
+
"Reading Time",
|
307 |
+
expanded=False,
|
308 |
+
)
|
309 |
+
|
310 |
+
with st_rt_expander:
|
311 |
+
st_rt_max_reading_time = st.slider(
|
312 |
+
label="Max reading time (in minutes)",
|
313 |
+
value=5,
|
314 |
+
min_value=0,
|
315 |
+
max_value=3600,
|
316 |
+
step=5,
|
317 |
+
key="rt_max_reading_time",
|
318 |
+
)
|
319 |
+
|
320 |
+
st_rt_truncate = st.checkbox(
|
321 |
+
"Truncate",
|
322 |
+
value=False,
|
323 |
+
help="Truncate the text to the max reading time",
|
324 |
+
key="rt_truncate",
|
325 |
+
)
|
326 |
+
|
327 |
+
settings["ReadingTime"] = {"max_time": st_rt_max_reading_time, "truncate": st_rt_truncate}
|
328 |
+
|
329 |
if "FactualConsistency" in st_enabled_scanners:
|
330 |
st_fc_expander = st.sidebar.expander(
|
331 |
"FactualConsistency",
|
|
|
357 |
height=200,
|
358 |
).split("\n")
|
359 |
|
360 |
+
st_regex_is_blocked = st.checkbox("Is blocked", value=False, key="regex_is_blocked")
|
|
|
|
|
|
|
|
|
|
|
361 |
|
362 |
+
st_regex_redact = st.checkbox(
|
363 |
+
"Redact",
|
364 |
+
value=False,
|
365 |
+
help="Replace the matched bad patterns with [REDACTED]",
|
366 |
+
key="regex_redact",
|
367 |
)
|
368 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
369 |
settings["Regex"] = {
|
370 |
+
"patterns": st_regex_patterns,
|
371 |
+
"is_blocked": st_regex_is_blocked,
|
372 |
+
"redact": st_regex_redact,
|
373 |
}
|
374 |
|
375 |
if "Relevance" in st_enabled_scanners:
|
|
|
455 |
with st_tox_expander:
|
456 |
st_tox_threshold = st.slider(
|
457 |
label="Threshold",
|
458 |
+
value=0.5,
|
459 |
+
min_value=0.0,
|
460 |
max_value=1.0,
|
461 |
step=0.05,
|
462 |
key="toxicity_threshold",
|
|
|
463 |
)
|
464 |
|
465 |
+
st_tox_match_type = st.selectbox(
|
466 |
+
"Match type",
|
467 |
+
[e.value for e in ToxicityMatchType],
|
468 |
+
index=1,
|
469 |
+
key="toxicity_match_type",
|
470 |
+
)
|
471 |
+
|
472 |
+
settings["Toxicity"] = {
|
473 |
+
"threshold": st_tox_threshold,
|
474 |
+
"match_type": ToxicityMatchType(st_tox_match_type),
|
475 |
+
}
|
476 |
+
|
477 |
+
if "URLReachability" in st_enabled_scanners:
|
478 |
+
st_url_expander = st.sidebar.expander(
|
479 |
+
"URL Reachability",
|
480 |
+
expanded=False,
|
481 |
+
)
|
482 |
+
|
483 |
+
if st_url_expander:
|
484 |
+
settings["URLReachability"] = {}
|
485 |
|
486 |
return st_enabled_scanners, settings
|
487 |
|
prompt.py
CHANGED
@@ -6,6 +6,9 @@ from typing import Dict, List
|
|
6 |
import streamlit as st
|
7 |
from llm_guard.input_scanners import get_scanner_by_name
|
8 |
from llm_guard.input_scanners.anonymize import default_entity_types
|
|
|
|
|
|
|
9 |
from llm_guard.vault import Vault
|
10 |
from streamlit_tags import st_tags
|
11 |
|
@@ -15,6 +18,7 @@ logger = logging.getLogger("llm-guard-playground")
|
|
15 |
def init_settings() -> (List, Dict):
|
16 |
all_scanners = [
|
17 |
"Anonymize",
|
|
|
18 |
"BanSubstrings",
|
19 |
"BanTopics",
|
20 |
"Code",
|
@@ -77,7 +81,10 @@ def init_settings() -> (List, Dict):
|
|
77 |
"Preamble", value="Text to prepend to sanitized prompt: "
|
78 |
)
|
79 |
st_anon_use_faker = st.checkbox(
|
80 |
-
"Use Faker",
|
|
|
|
|
|
|
81 |
)
|
82 |
st_anon_threshold = st.slider(
|
83 |
label="Threshold",
|
@@ -97,6 +104,36 @@ def init_settings() -> (List, Dict):
|
|
97 |
"threshold": st_anon_threshold,
|
98 |
}
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
if "BanSubstrings" in st_enabled_scanners:
|
101 |
st_bs_expander = st.sidebar.expander(
|
102 |
"Ban Substrings",
|
@@ -110,10 +147,14 @@ def init_settings() -> (List, Dict):
|
|
110 |
height=200,
|
111 |
).split("\n")
|
112 |
|
113 |
-
st_bs_match_type = st.selectbox(
|
114 |
-
|
115 |
-
|
116 |
-
|
|
|
|
|
|
|
|
|
117 |
|
118 |
settings["BanSubstrings"] = {
|
119 |
"substrings": st_bs_substrings,
|
@@ -166,18 +207,11 @@ def init_settings() -> (List, Dict):
|
|
166 |
default=["python"],
|
167 |
)
|
168 |
|
169 |
-
|
170 |
-
|
171 |
-
allowed_languages = None
|
172 |
-
denied_languages = None
|
173 |
-
if st_cd_mode == "allowed":
|
174 |
-
allowed_languages = st_cd_languages
|
175 |
-
elif st_cd_mode == "denied":
|
176 |
-
denied_languages = st_cd_languages
|
177 |
|
178 |
settings["Code"] = {
|
179 |
-
"
|
180 |
-
"
|
181 |
}
|
182 |
|
183 |
if "Language" in st_enabled_scanners:
|
@@ -214,8 +248,16 @@ def init_settings() -> (List, Dict):
|
|
214 |
default=["en"],
|
215 |
)
|
216 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
settings["Language"] = {
|
218 |
"valid_languages": st_lan_valid_language,
|
|
|
219 |
}
|
220 |
|
221 |
if "PromptInjection" in st_enabled_scanners:
|
@@ -234,8 +276,16 @@ def init_settings() -> (List, Dict):
|
|
234 |
key="prompt_injection_threshold",
|
235 |
)
|
236 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
settings["PromptInjection"] = {
|
238 |
"threshold": st_pi_threshold,
|
|
|
239 |
}
|
240 |
|
241 |
if "Regex" in st_enabled_scanners:
|
@@ -251,28 +301,19 @@ def init_settings() -> (List, Dict):
|
|
251 |
height=200,
|
252 |
).split("\n")
|
253 |
|
254 |
-
|
255 |
-
"Match type",
|
256 |
-
["good", "bad"],
|
257 |
-
index=1,
|
258 |
-
help="good: allow only good patterns, bad: ban bad patterns",
|
259 |
-
)
|
260 |
|
261 |
-
|
262 |
-
"Redact",
|
|
|
|
|
|
|
263 |
)
|
264 |
|
265 |
-
good_patterns = None
|
266 |
-
bad_patterns = None
|
267 |
-
if st_regex_type == "good":
|
268 |
-
good_patterns = st_regex_patterns
|
269 |
-
elif st_regex_type == "bad":
|
270 |
-
bad_patterns = st_regex_patterns
|
271 |
-
|
272 |
settings["Regex"] = {
|
273 |
-
"
|
274 |
-
"
|
275 |
-
"redact":
|
276 |
}
|
277 |
|
278 |
if "Secrets" in st_enabled_scanners:
|
@@ -347,8 +388,16 @@ def init_settings() -> (List, Dict):
|
|
347 |
key="toxicity_threshold",
|
348 |
)
|
349 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
350 |
settings["Toxicity"] = {
|
351 |
"threshold": st_tox_threshold,
|
|
|
352 |
}
|
353 |
|
354 |
return st_enabled_scanners, settings
|
|
|
6 |
import streamlit as st
|
7 |
from llm_guard.input_scanners import get_scanner_by_name
|
8 |
from llm_guard.input_scanners.anonymize import default_entity_types
|
9 |
+
from llm_guard.input_scanners.language import MatchType as LanguageMatchType
|
10 |
+
from llm_guard.input_scanners.prompt_injection import MatchType as PromptInjectionMatchType
|
11 |
+
from llm_guard.input_scanners.toxicity import MatchType as ToxicityMatchType
|
12 |
from llm_guard.vault import Vault
|
13 |
from streamlit_tags import st_tags
|
14 |
|
|
|
18 |
def init_settings() -> (List, Dict):
|
19 |
all_scanners = [
|
20 |
"Anonymize",
|
21 |
+
"BanCompetitors",
|
22 |
"BanSubstrings",
|
23 |
"BanTopics",
|
24 |
"Code",
|
|
|
81 |
"Preamble", value="Text to prepend to sanitized prompt: "
|
82 |
)
|
83 |
st_anon_use_faker = st.checkbox(
|
84 |
+
"Use Faker",
|
85 |
+
value=False,
|
86 |
+
help="Use Faker library to generate fake data",
|
87 |
+
key="anon_use_faker",
|
88 |
)
|
89 |
st_anon_threshold = st.slider(
|
90 |
label="Threshold",
|
|
|
104 |
"threshold": st_anon_threshold,
|
105 |
}
|
106 |
|
107 |
+
if "BanCompetitors" in st_enabled_scanners:
|
108 |
+
st_bc_expander = st.sidebar.expander(
|
109 |
+
"Ban Competitors",
|
110 |
+
expanded=False,
|
111 |
+
)
|
112 |
+
|
113 |
+
with st_bc_expander:
|
114 |
+
st_bc_competitors = st_tags(
|
115 |
+
label="List of competitors",
|
116 |
+
text="Type and press enter",
|
117 |
+
value=["openai", "anthropic", "deepmind", "google"],
|
118 |
+
suggestions=[],
|
119 |
+
maxtags=30,
|
120 |
+
key="bc_competitors",
|
121 |
+
)
|
122 |
+
|
123 |
+
st_bc_threshold = st.slider(
|
124 |
+
label="Threshold",
|
125 |
+
value=0.5,
|
126 |
+
min_value=0.0,
|
127 |
+
max_value=1.0,
|
128 |
+
step=0.05,
|
129 |
+
key="ban_competitors_threshold",
|
130 |
+
)
|
131 |
+
|
132 |
+
settings["BanCompetitors"] = {
|
133 |
+
"competitors": st_bc_competitors,
|
134 |
+
"threshold": st_bc_threshold,
|
135 |
+
}
|
136 |
+
|
137 |
if "BanSubstrings" in st_enabled_scanners:
|
138 |
st_bs_expander = st.sidebar.expander(
|
139 |
"Ban Substrings",
|
|
|
147 |
height=200,
|
148 |
).split("\n")
|
149 |
|
150 |
+
st_bs_match_type = st.selectbox(
|
151 |
+
"Match type", ["str", "word"], index=0, key="bs_match_type"
|
152 |
+
)
|
153 |
+
st_bs_case_sensitive = st.checkbox(
|
154 |
+
"Case sensitive", value=False, key="bs_case_sensitive"
|
155 |
+
)
|
156 |
+
st_bs_redact = st.checkbox("Redact", value=False, key="bs_redact")
|
157 |
+
st_bs_contains_all = st.checkbox("Contains all", value=False, key="bs_contains_all")
|
158 |
|
159 |
settings["BanSubstrings"] = {
|
160 |
"substrings": st_bs_substrings,
|
|
|
207 |
default=["python"],
|
208 |
)
|
209 |
|
210 |
+
st_cd_is_blocked = st.checkbox("Is blocked", value=False, key="code_is_blocked")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
|
212 |
settings["Code"] = {
|
213 |
+
"languages": st_cd_languages,
|
214 |
+
"is_blocked": st_cd_is_blocked,
|
215 |
}
|
216 |
|
217 |
if "Language" in st_enabled_scanners:
|
|
|
248 |
default=["en"],
|
249 |
)
|
250 |
|
251 |
+
st_lan_match_type = st.selectbox(
|
252 |
+
"Match type",
|
253 |
+
[e.value for e in LanguageMatchType],
|
254 |
+
index=1,
|
255 |
+
key="language_match_type",
|
256 |
+
)
|
257 |
+
|
258 |
settings["Language"] = {
|
259 |
"valid_languages": st_lan_valid_language,
|
260 |
+
"match_type": st_lan_match_type,
|
261 |
}
|
262 |
|
263 |
if "PromptInjection" in st_enabled_scanners:
|
|
|
276 |
key="prompt_injection_threshold",
|
277 |
)
|
278 |
|
279 |
+
st_pi_match_type = st.selectbox(
|
280 |
+
"Match type",
|
281 |
+
[e.value for e in PromptInjectionMatchType],
|
282 |
+
index=1,
|
283 |
+
key="prompt_injection_match_type",
|
284 |
+
)
|
285 |
+
|
286 |
settings["PromptInjection"] = {
|
287 |
"threshold": st_pi_threshold,
|
288 |
+
"match_type": st_pi_match_type,
|
289 |
}
|
290 |
|
291 |
if "Regex" in st_enabled_scanners:
|
|
|
301 |
height=200,
|
302 |
).split("\n")
|
303 |
|
304 |
+
st_regex_is_blocked = st.checkbox("Is blocked", value=False, key="regex_is_blocked")
|
|
|
|
|
|
|
|
|
|
|
305 |
|
306 |
+
st_regex_redact = st.checkbox(
|
307 |
+
"Redact",
|
308 |
+
value=False,
|
309 |
+
help="Replace the matched bad patterns with [REDACTED]",
|
310 |
+
key="regex_redact",
|
311 |
)
|
312 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
settings["Regex"] = {
|
314 |
+
"patterns": st_regex_patterns,
|
315 |
+
"is_blocked": st_regex_is_blocked,
|
316 |
+
"redact": st_regex_redact,
|
317 |
}
|
318 |
|
319 |
if "Secrets" in st_enabled_scanners:
|
|
|
388 |
key="toxicity_threshold",
|
389 |
)
|
390 |
|
391 |
+
st_tox_match_type = st.selectbox(
|
392 |
+
"Match type",
|
393 |
+
[e.value for e in ToxicityMatchType],
|
394 |
+
index=1,
|
395 |
+
key="toxicity_match_type",
|
396 |
+
)
|
397 |
+
|
398 |
settings["Toxicity"] = {
|
399 |
"threshold": st_tox_threshold,
|
400 |
+
"match_type": st_tox_match_type,
|
401 |
}
|
402 |
|
403 |
return st_enabled_scanners, settings
|
requirements.txt
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
-
llm-guard==0.3.
|
2 |
-
llm-guard[onnxruntime]==0.3.
|
3 |
-
pandas==2.
|
4 |
-
streamlit==1.
|
5 |
streamlit-tags==1.2.8
|
|
|
1 |
+
llm-guard==0.3.7
|
2 |
+
llm-guard[onnxruntime]==0.3.7
|
3 |
+
pandas==2.2.0
|
4 |
+
streamlit==1.30.0
|
5 |
streamlit-tags==1.2.8
|