Spaces:
Running
Running
Demo updates Sept 2025 (#7)
Browse files- enhancement: update the model (d030d25796ce0ea019eb2a6c2f207a2378f06bf8)
- add a network subgraph (5c083ab760b9ce8c3f5b5d09d31df68edeef992e)
Co-authored-by: Inge V <[email protected]>
- app.py +14 -8
- executor.py +89 -22
- requirements.txt +1 -1
app.py
CHANGED
|
@@ -6,6 +6,7 @@ from executor import clear_previous_risks, clear_previous_mitigations, risk_iden
|
|
| 6 |
logging.basicConfig(level=logging.INFO)
|
| 7 |
logger = logging.getLogger(__name__)
|
| 8 |
|
|
|
|
| 9 |
class UI:
|
| 10 |
|
| 11 |
def __init__(self):
|
|
@@ -48,14 +49,14 @@ class UI:
|
|
| 48 |
)
|
| 49 |
self.model_name_or_path = gr.Dropdown(
|
| 50 |
#choices=['codellama/codellama-34b-instruct-hf', 'google/flan-t5-xl', 'google/flan-t5-xxl', 'google/flan-ul2', 'ibm/granite-13b-instruct-v2', 'ibm/granite-3-3-8b-instruct', 'ibm/granite-20b-multilingual', 'ibm/granite-3-2-8b-instruct-preview-rc', 'ibm/granite-3-2b-instruct', 'ibm/granite-3-8b-instruct', 'ibm/granite-34b-code-instruct', 'ibm/granite-3b-code-instruct', 'ibm/granite-8b-code-instruct', 'ibm/granite-guardian-3-2b', 'ibm/granite-guardian-3-8b', 'meta-llama/llama-2-13b-chat', 'meta-llama/llama-3-1-70b-instruct', 'meta-llama/llama-3-1-8b-instruct', 'meta-llama/llama-3-2-11b-vision-instruct', 'meta-llama/llama-3-2-1b-instruct', 'meta-llama/llama-3-2-3b-instruct', 'meta-llama/llama-3-2-90b-vision-instruct', 'meta-llama/llama-3-3-70b-instruct', 'meta-llama/llama-3-405b-instruct', 'meta-llama/llama-guard-3-11b-vision', 'mistralai/mistral-large', 'mistralai/mixtral-8x7b-instruct-v01'],
|
| 51 |
-
choices=["
|
| 52 |
-
value="
|
| 53 |
multiselect=False,
|
| 54 |
label="Choose language model to use",
|
| 55 |
info="Language model used to assess risks (This is not the model being assessed).",
|
| 56 |
interactive=True
|
| 57 |
)
|
| 58 |
-
examples = gr.Examples([["A medical chatbot for a triage system to
|
| 59 |
["Building a customer support agent that automatically triages common problems with services.", "ibm-risk-atlas"]],
|
| 60 |
[self.usecase, self.taxonomy],
|
| 61 |
label='Example use cases', example_labels=["Medical chatbot", "Customer service agent"]
|
|
@@ -92,12 +93,18 @@ class UI:
|
|
| 92 |
self.benchmarks_text = gr.Markdown()
|
| 93 |
self.benchmarks = gr.DataFrame(label=None, visible=False)
|
| 94 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
self.download = gr.DownloadButton("Download JSON", visible=False)
|
| 96 |
|
| 97 |
gr.Markdown("---")
|
| 98 |
gr.Markdown("<br>")
|
| 99 |
|
| 100 |
-
|
| 101 |
def load_css(self):
|
| 102 |
with open("static/style.css", "r") as file:
|
| 103 |
self.css = file.read()
|
|
@@ -117,7 +124,7 @@ class UI:
|
|
| 117 |
self.risk_execute.click(
|
| 118 |
fn=clear_previous_risks,
|
| 119 |
inputs=[],
|
| 120 |
-
outputs=[self.assessment_sec, self.risks, self.assessed_risks, self.download, self.assessed_risk_definition, self.relatedrisks, self.mitigations, self.benchmarks, self.mitigations_text],
|
| 121 |
).then(
|
| 122 |
fn=risk_identifier,
|
| 123 |
inputs=[
|
|
@@ -132,17 +139,16 @@ class UI:
|
|
| 132 |
self.assessed_risks.select(
|
| 133 |
fn=clear_previous_mitigations,
|
| 134 |
inputs=[],
|
| 135 |
-
outputs=[self.assessed_risk_definition, self.relatedrisks, self.mitigations, self.benchmarks, self.mitigations_text]
|
| 136 |
).then(
|
| 137 |
fn=mitigations,
|
| 138 |
inputs=[self.assessed_risks, self.taxonomy],
|
| 139 |
# NOTETOSELF: Intent based risk is stored in self.risk (if needed)
|
| 140 |
-
outputs=[self.assessed_risk_definition, self.relatedrisks, self.mitigations, self.benchmarks, self.mitigations_text]
|
| 141 |
)
|
| 142 |
|
| 143 |
return demo
|
| 144 |
|
| 145 |
-
|
| 146 |
def run(self):
|
| 147 |
self.ui = self.layout()
|
| 148 |
self.ui.queue().launch(allowed_paths=["static/"], ssr_mode=False)
|
|
|
|
| 6 |
logging.basicConfig(level=logging.INFO)
|
| 7 |
logger = logging.getLogger(__name__)
|
| 8 |
|
| 9 |
+
|
| 10 |
class UI:
|
| 11 |
|
| 12 |
def __init__(self):
|
|
|
|
| 49 |
)
|
| 50 |
self.model_name_or_path = gr.Dropdown(
|
| 51 |
#choices=['codellama/codellama-34b-instruct-hf', 'google/flan-t5-xl', 'google/flan-t5-xxl', 'google/flan-ul2', 'ibm/granite-13b-instruct-v2', 'ibm/granite-3-3-8b-instruct', 'ibm/granite-20b-multilingual', 'ibm/granite-3-2-8b-instruct-preview-rc', 'ibm/granite-3-2b-instruct', 'ibm/granite-3-8b-instruct', 'ibm/granite-34b-code-instruct', 'ibm/granite-3b-code-instruct', 'ibm/granite-8b-code-instruct', 'ibm/granite-guardian-3-2b', 'ibm/granite-guardian-3-8b', 'meta-llama/llama-2-13b-chat', 'meta-llama/llama-3-1-70b-instruct', 'meta-llama/llama-3-1-8b-instruct', 'meta-llama/llama-3-2-11b-vision-instruct', 'meta-llama/llama-3-2-1b-instruct', 'meta-llama/llama-3-2-3b-instruct', 'meta-llama/llama-3-2-90b-vision-instruct', 'meta-llama/llama-3-3-70b-instruct', 'meta-llama/llama-3-405b-instruct', 'meta-llama/llama-guard-3-11b-vision', 'mistralai/mistral-large', 'mistralai/mixtral-8x7b-instruct-v01'],
|
| 52 |
+
choices=["meta-llama/llama-3-3-70b-instruct"],
|
| 53 |
+
value="meta-llama/llama-3-3-70b-instruct",
|
| 54 |
multiselect=False,
|
| 55 |
label="Choose language model to use",
|
| 56 |
info="Language model used to assess risks (This is not the model being assessed).",
|
| 57 |
interactive=True
|
| 58 |
)
|
| 59 |
+
examples = gr.Examples([["A medical chatbot for a triage system to assess symptoms and provide advice based on patient medical history and conditions. The chatbot will analyze the patient input, identify potential medical issues, and offer recommendations to the patient or healthcare provider.", "ibm-risk-atlas"],
|
| 60 |
["Building a customer support agent that automatically triages common problems with services.", "ibm-risk-atlas"]],
|
| 61 |
[self.usecase, self.taxonomy],
|
| 62 |
label='Example use cases', example_labels=["Medical chatbot", "Customer service agent"]
|
|
|
|
| 93 |
self.benchmarks_text = gr.Markdown()
|
| 94 |
self.benchmarks = gr.DataFrame(label=None, visible=False)
|
| 95 |
|
| 96 |
+
gr.Markdown(
|
| 97 |
+
"""<h2>Network </h2>
|
| 98 |
+
Select a potential risk to see its network. """
|
| 99 |
+
)
|
| 100 |
+
|
| 101 |
+
self.networks = gr.Markdown()
|
| 102 |
+
|
| 103 |
self.download = gr.DownloadButton("Download JSON", visible=False)
|
| 104 |
|
| 105 |
gr.Markdown("---")
|
| 106 |
gr.Markdown("<br>")
|
| 107 |
|
|
|
|
| 108 |
def load_css(self):
|
| 109 |
with open("static/style.css", "r") as file:
|
| 110 |
self.css = file.read()
|
|
|
|
| 124 |
self.risk_execute.click(
|
| 125 |
fn=clear_previous_risks,
|
| 126 |
inputs=[],
|
| 127 |
+
outputs=[self.assessment_sec, self.risks, self.assessed_risks, self.download, self.assessed_risk_definition, self.relatedrisks, self.mitigations, self.benchmarks, self.mitigations_text, self.networks],
|
| 128 |
).then(
|
| 129 |
fn=risk_identifier,
|
| 130 |
inputs=[
|
|
|
|
| 139 |
self.assessed_risks.select(
|
| 140 |
fn=clear_previous_mitigations,
|
| 141 |
inputs=[],
|
| 142 |
+
outputs=[self.assessed_risk_definition, self.relatedrisks, self.mitigations, self.benchmarks, self.mitigations_text, self.networks]
|
| 143 |
).then(
|
| 144 |
fn=mitigations,
|
| 145 |
inputs=[self.assessed_risks, self.taxonomy],
|
| 146 |
# NOTETOSELF: Intent based risk is stored in self.risk (if needed)
|
| 147 |
+
outputs=[self.assessed_risk_definition, self.relatedrisks, self.mitigations, self.benchmarks, self.mitigations_text, self.networks]
|
| 148 |
)
|
| 149 |
|
| 150 |
return demo
|
| 151 |
|
|
|
|
| 152 |
def run(self):
|
| 153 |
self.ui = self.layout()
|
| 154 |
self.ui.queue().launch(allowed_paths=["static/"], ssr_mode=False)
|
executor.py
CHANGED
|
@@ -1,14 +1,5 @@
|
|
| 1 |
-
from ast import Attribute
|
| 2 |
-
from dotenv import load_dotenv
|
| 3 |
-
|
| 4 |
-
load_dotenv(override=True)
|
| 5 |
-
|
| 6 |
-
import re
|
| 7 |
import os
|
| 8 |
import pandas as pd
|
| 9 |
-
import json
|
| 10 |
-
from typing import List, Dict, Any
|
| 11 |
-
import pandas as pd
|
| 12 |
import gradio as gr
|
| 13 |
import datetime
|
| 14 |
from pathlib import Path
|
|
@@ -19,6 +10,9 @@ from risk_atlas_nexus.blocks.inference.params import WMLInferenceEngineParams
|
|
| 19 |
from risk_atlas_nexus.library import RiskAtlasNexus
|
| 20 |
|
| 21 |
from functools import lru_cache
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
# Load the taxonomies
|
| 24 |
ran = RiskAtlasNexus() # type: ignore
|
|
@@ -27,14 +21,53 @@ ran = RiskAtlasNexus() # type: ignore
|
|
| 27 |
def clear_previous_risks():
|
| 28 |
return gr.Markdown("""<h2> Potential Risks </h2> """), [], gr.Dataset(samples=[],
|
| 29 |
sample_labels=[],
|
| 30 |
-
samples_per_page=50, visible=False), gr.DownloadButton("Download JSON", visible=False, ), "", gr.Dataset(samples=[], sample_labels=[], visible=False), gr.DataFrame([], wrap=True, show_copy_button=True, show_search="search", visible=False), gr.DataFrame([], wrap=True, show_copy_button=True, show_search="search", visible=False), gr.Markdown(" ")
|
| 31 |
|
| 32 |
def clear_previous_mitigations():
|
| 33 |
-
return "", gr.Dataset(samples=[], sample_labels=[], visible=False), gr.DataFrame([], wrap=True, show_copy_button=True, show_search="search", visible=False), gr.DataFrame([], wrap=True, show_copy_button=True, show_search="search", visible=False), gr.Markdown(" ")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
|
| 35 |
@lru_cache
|
| 36 |
def risk_identifier(usecase: str,
|
| 37 |
-
model_name_or_path: str = "
|
| 38 |
taxonomy: str = "ibm-risk-atlas"): # -> List[Dict[str, Any]]: #pd.DataFrame:
|
| 39 |
|
| 40 |
downloadable = False
|
|
@@ -50,12 +83,15 @@ def risk_identifier(usecase: str,
|
|
| 50 |
), # type: ignore
|
| 51 |
)
|
| 52 |
|
| 53 |
-
|
| 54 |
usecases=[usecase],
|
| 55 |
inference_engine=inference_engine,
|
| 56 |
taxonomy=taxonomy,
|
|
|
|
| 57 |
max_risk=5
|
| 58 |
-
)
|
|
|
|
|
|
|
| 59 |
|
| 60 |
|
| 61 |
sample_labels = [r.name if r else r.id for r in risks]
|
|
@@ -74,26 +110,56 @@ def risk_identifier(usecase: str,
|
|
| 74 |
f.write(json.dumps(data, indent=4))
|
| 75 |
downloadable = True
|
| 76 |
|
| 77 |
-
|
| 78 |
-
#return out_df
|
| 79 |
return out_sec, gr.State(risks), gr.Dataset(samples=[r.id for r in risks],
|
| 80 |
sample_labels=sample_labels,
|
| 81 |
samples_per_page=50, visible=True, label="Estimated by an LLM."), gr.DownloadButton("Download JSON", "static/download.json", visible=(downloadable and len(risks) > 0))
|
| 82 |
|
| 83 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
@lru_cache
|
| 85 |
-
def mitigations(riskid: str, taxonomy: str) -> tuple[gr.Markdown, gr.Dataset, gr.DataFrame, gr.DataFrame, gr.Markdown]:
|
| 86 |
"""
|
| 87 |
For a specific risk (riskid), returns
|
| 88 |
(a) a risk description
|
| 89 |
(b) related risks - as a dataset
|
| 90 |
(c) mitigations
|
| 91 |
-
(d) related
|
|
|
|
| 92 |
|
| 93 |
"""
|
| 94 |
|
| 95 |
try:
|
| 96 |
-
|
|
|
|
| 97 |
risk_sec = f"<h3>Description: </h3> {risk_desc}"
|
| 98 |
except AttributeError:
|
| 99 |
risk_sec = ""
|
|
@@ -123,8 +189,7 @@ def mitigations(riskid: str, taxonomy: str) -> tuple[gr.Markdown, gr.Dataset, gr
|
|
| 123 |
# Use only actions related to primary risks
|
| 124 |
action_ids = ran.get_related_actions(id=riskid)
|
| 125 |
control_ids = ran.get_related_risk_controls(id=riskid)
|
| 126 |
-
|
| 127 |
-
|
| 128 |
# Sanitize outputs
|
| 129 |
if not related_risk_ids:
|
| 130 |
label = "No related risks found."
|
|
@@ -163,9 +228,11 @@ def mitigations(riskid: str, taxonomy: str) -> tuple[gr.Markdown, gr.Dataset, gr
|
|
| 163 |
|
| 164 |
status = gr.Markdown(" ") if len(mitdf) > 0 else gr.Markdown("No mitigations found.")
|
| 165 |
|
|
|
|
|
|
|
| 166 |
return (gr.Markdown(risk_sec),
|
| 167 |
gr.Dataset(samples=samples, label=label, sample_labels=sample_labels, visible=True),
|
| 168 |
gr.DataFrame(mitdf, wrap=True, show_copy_button=True, show_search="search", label=alabel, visible=True),
|
| 169 |
gr.DataFrame(aievalsdf, wrap=True, show_copy_button=True, show_search="search", label=blabel, visible=True),
|
| 170 |
-
status)
|
| 171 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import os
|
| 2 |
import pandas as pd
|
|
|
|
|
|
|
|
|
|
| 3 |
import gradio as gr
|
| 4 |
import datetime
|
| 5 |
from pathlib import Path
|
|
|
|
| 10 |
from risk_atlas_nexus.library import RiskAtlasNexus
|
| 11 |
|
| 12 |
from functools import lru_cache
|
| 13 |
+
from dotenv import load_dotenv
|
| 14 |
+
|
| 15 |
+
load_dotenv(override=True)
|
| 16 |
|
| 17 |
# Load the taxonomies
|
| 18 |
ran = RiskAtlasNexus() # type: ignore
|
|
|
|
| 21 |
def clear_previous_risks():
|
| 22 |
return gr.Markdown("""<h2> Potential Risks </h2> """), [], gr.Dataset(samples=[],
|
| 23 |
sample_labels=[],
|
| 24 |
+
samples_per_page=50, visible=False), gr.DownloadButton("Download JSON", visible=False, ), "", gr.Dataset(samples=[], sample_labels=[], visible=False), gr.DataFrame([], wrap=True, show_copy_button=True, show_search="search", visible=False), gr.DataFrame([], wrap=True, show_copy_button=True, show_search="search", visible=False), gr.Markdown(" "), gr.Markdown(" "),
|
| 25 |
|
| 26 |
def clear_previous_mitigations():
|
| 27 |
+
return "", gr.Dataset(samples=[], sample_labels=[], visible=False), gr.DataFrame([], wrap=True, show_copy_button=True, show_search="search", visible=False), gr.DataFrame([], wrap=True, show_copy_button=True, show_search="search", visible=False), gr.Markdown(" "), gr.Markdown(" ")
|
| 28 |
+
|
| 29 |
+
def generate_subgraph(risk):
|
| 30 |
+
lines =[f'```mermaid\n', '---\n'
|
| 31 |
+
'config:\n'
|
| 32 |
+
' layout: "tidy-tree"\n'
|
| 33 |
+
'---\n',
|
| 34 |
+
'mindmap\n']
|
| 35 |
+
|
| 36 |
+
lines.append(f' root(("{risk.name}"))\n')
|
| 37 |
+
# origin info
|
| 38 |
+
lines.append(f' Origins\n')
|
| 39 |
+
lines.append(f' Riskgroup: {risk.isPartOf}\n')
|
| 40 |
+
lines.append(f' Taxonomy: {risk.isDefinedByTaxonomy}\n')
|
| 41 |
+
|
| 42 |
+
# add related risks
|
| 43 |
+
rrs = ran.get_related_risks(id=risk.id)
|
| 44 |
+
if len(rrs) > 0:
|
| 45 |
+
lines.append(f' Related Risks\n')
|
| 46 |
+
for rr in rrs:
|
| 47 |
+
lines.append(f' {rr.name}\n')
|
| 48 |
+
|
| 49 |
+
# add related evals
|
| 50 |
+
revals = ran.get_related_evaluations(risk_id=risk.id)
|
| 51 |
+
if len(revals) > 0:
|
| 52 |
+
lines.append(f' Related AI evaluations\n')
|
| 53 |
+
for reval in revals:
|
| 54 |
+
lines.append(f' {reval.name}\n')
|
| 55 |
+
|
| 56 |
+
# add related mitigations
|
| 57 |
+
rmits = get_controls_and_actions(risk.id, risk.isDefinedByTaxonomy)
|
| 58 |
+
if len(rmits) > 0:
|
| 59 |
+
lines.append(f' Related mitigations\n')
|
| 60 |
+
for rmit in rmits:
|
| 61 |
+
lines.append(f' {rmit}\n')
|
| 62 |
+
|
| 63 |
+
lines.append(f"```")
|
| 64 |
+
diagram_string = "".join(lines)
|
| 65 |
+
return gr.Markdown(value = diagram_string)
|
| 66 |
+
|
| 67 |
|
| 68 |
@lru_cache
|
| 69 |
def risk_identifier(usecase: str,
|
| 70 |
+
model_name_or_path: str = "meta-llama/llama-3-3-70b-instruct",
|
| 71 |
taxonomy: str = "ibm-risk-atlas"): # -> List[Dict[str, Any]]: #pd.DataFrame:
|
| 72 |
|
| 73 |
downloadable = False
|
|
|
|
| 83 |
), # type: ignore
|
| 84 |
)
|
| 85 |
|
| 86 |
+
risks_a = ran.identify_risks_from_usecases(# type: ignore
|
| 87 |
usecases=[usecase],
|
| 88 |
inference_engine=inference_engine,
|
| 89 |
taxonomy=taxonomy,
|
| 90 |
+
zero_shot_only=True,
|
| 91 |
max_risk=5
|
| 92 |
+
)
|
| 93 |
+
|
| 94 |
+
risks = risks_a[0]
|
| 95 |
|
| 96 |
|
| 97 |
sample_labels = [r.name if r else r.id for r in risks]
|
|
|
|
| 110 |
f.write(json.dumps(data, indent=4))
|
| 111 |
downloadable = True
|
| 112 |
|
| 113 |
+
# return out_df
|
|
|
|
| 114 |
return out_sec, gr.State(risks), gr.Dataset(samples=[r.id for r in risks],
|
| 115 |
sample_labels=sample_labels,
|
| 116 |
samples_per_page=50, visible=True, label="Estimated by an LLM."), gr.DownloadButton("Download JSON", "static/download.json", visible=(downloadable and len(risks) > 0))
|
| 117 |
|
| 118 |
|
| 119 |
+
def get_controls_and_actions(riskid, taxonomy):
|
| 120 |
+
selected_risk = ran.get_risk(id=riskid)
|
| 121 |
+
related_risk_ids = [r.id for r in ran.get_related_risks(id=riskid)]
|
| 122 |
+
action_ids = []
|
| 123 |
+
control_ids =[]
|
| 124 |
+
|
| 125 |
+
if taxonomy == "ibm-risk-atlas":
|
| 126 |
+
# look for actions associated with related risks
|
| 127 |
+
if related_risk_ids:
|
| 128 |
+
for i in related_risk_ids:
|
| 129 |
+
rai = ran.get_related_actions(id=i)
|
| 130 |
+
if rai:
|
| 131 |
+
action_ids += rai
|
| 132 |
+
|
| 133 |
+
rac = ran.get_related_risk_controls(id=i)
|
| 134 |
+
if rac:
|
| 135 |
+
control_ids += rac
|
| 136 |
+
|
| 137 |
+
else:
|
| 138 |
+
action_ids = []
|
| 139 |
+
control_ids = []
|
| 140 |
+
else:
|
| 141 |
+
# Use only actions related to primary risks
|
| 142 |
+
action_ids = ran.get_related_actions(id=riskid)
|
| 143 |
+
control_ids = ran.get_related_risk_controls(id=riskid)
|
| 144 |
+
|
| 145 |
+
return [ran.get_action_by_id(i).name for i in action_ids] + [ran.get_risk_control(i.id).name for i in control_ids] #type: ignore
|
| 146 |
+
|
| 147 |
+
|
| 148 |
@lru_cache
|
| 149 |
+
def mitigations(riskid: str, taxonomy: str) -> tuple[gr.Markdown, gr.Dataset, gr.DataFrame, gr.DataFrame, gr.Markdown, gr.Markdown]:
|
| 150 |
"""
|
| 151 |
For a specific risk (riskid), returns
|
| 152 |
(a) a risk description
|
| 153 |
(b) related risks - as a dataset
|
| 154 |
(c) mitigations
|
| 155 |
+
(d) related AI evaluations
|
| 156 |
+
(e) A subgraph of risk to mitigations
|
| 157 |
|
| 158 |
"""
|
| 159 |
|
| 160 |
try:
|
| 161 |
+
selected_risk = ran.get_risk(id=riskid)
|
| 162 |
+
risk_desc = selected_risk.description # type: ignore
|
| 163 |
risk_sec = f"<h3>Description: </h3> {risk_desc}"
|
| 164 |
except AttributeError:
|
| 165 |
risk_sec = ""
|
|
|
|
| 189 |
# Use only actions related to primary risks
|
| 190 |
action_ids = ran.get_related_actions(id=riskid)
|
| 191 |
control_ids = ran.get_related_risk_controls(id=riskid)
|
| 192 |
+
|
|
|
|
| 193 |
# Sanitize outputs
|
| 194 |
if not related_risk_ids:
|
| 195 |
label = "No related risks found."
|
|
|
|
| 228 |
|
| 229 |
status = gr.Markdown(" ") if len(mitdf) > 0 else gr.Markdown("No mitigations found.")
|
| 230 |
|
| 231 |
+
fig = gr.Markdown(" ") if not selected_risk else generate_subgraph(selected_risk)
|
| 232 |
+
|
| 233 |
return (gr.Markdown(risk_sec),
|
| 234 |
gr.Dataset(samples=samples, label=label, sample_labels=sample_labels, visible=True),
|
| 235 |
gr.DataFrame(mitdf, wrap=True, show_copy_button=True, show_search="search", label=alabel, visible=True),
|
| 236 |
gr.DataFrame(aievalsdf, wrap=True, show_copy_button=True, show_search="search", label=blabel, visible=True),
|
| 237 |
+
status, fig)
|
| 238 |
|
requirements.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
gradio==5.
|
| 2 |
pydantic==2.9.2
|
| 3 |
linkml==1.8.6
|
| 4 |
linkml_runtime==1.8.3
|
|
|
|
| 1 |
+
gradio==5.45.0
|
| 2 |
pydantic==2.9.2
|
| 3 |
linkml==1.8.6
|
| 4 |
linkml_runtime==1.8.3
|