rahulnair23 ingelise commited on
Commit
9cab8a9
·
verified ·
1 Parent(s): b6d3e2b

Demo updates Sept 2025 (#7)

Browse files

- enhancement: update the model (d030d25796ce0ea019eb2a6c2f207a2378f06bf8)
- add a network subgraph (5c083ab760b9ce8c3f5b5d09d31df68edeef992e)


Co-authored-by: Inge V <[email protected]>

Files changed (3) hide show
  1. app.py +14 -8
  2. executor.py +89 -22
  3. 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=["ibm/granite-3-3-8b-instruct"],
52
- value="ibm/granite-3-3-8b-instruct",
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 assesses symptoms and provide advice based on patient medical history and current condition. The chatbot will analyze the patient input, identify potential medical issues, and offer recommendations to the patient or healthcare provider.", "ibm-risk-atlas"],
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 = "ibm/granite-3-3-8b-instruct",
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
- risks = ran.identify_risks_from_usecases( # type: ignore
54
  usecases=[usecase],
55
  inference_engine=inference_engine,
56
  taxonomy=taxonomy,
 
57
  max_risk=5
58
- )[0]
 
 
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 ai evaluations
 
92
 
93
  """
94
 
95
  try:
96
- risk_desc = ran.get_risk(id=riskid).description # type: ignore
 
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.18.0
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