Dave67350 commited on
Commit
09a7a4f
·
verified ·
1 Parent(s): b0a4524

Update tools/ai_act_generator.py

Browse files
Files changed (1) hide show
  1. tools/ai_act_generator.py +46 -61
tools/ai_act_generator.py CHANGED
@@ -2,23 +2,14 @@
2
  # coding=utf-8
3
  import csv
4
  import datetime
5
- import mimetypes
6
  import os
7
  import re
8
- import shutil
9
- from typing import Optional
10
-
11
- from smolagents.agent_types import AgentAudio, AgentImage, AgentText, handle_agent_output_types
12
- from smolagents.agents import ActionStep, MultiStepAgent
13
- from smolagents.memory import MemoryStep
14
- from smolagents.utils import _is_package_available
15
-
16
- import gradio as gr
17
  from fpdf import FPDF
 
18
  from langdetect import detect
19
 
20
- # === PDF Export Function with Language Option ===
21
- def export_text_to_pdf(text, output_path=None, language="fr"):
22
  if output_path is None:
23
  timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
24
  output_path = f"ai_act_register_{timestamp}.pdf"
@@ -32,20 +23,21 @@ def export_text_to_pdf(text, output_path=None, language="fr"):
32
  pdf.set_text_color(0, 51, 102)
33
  title = "Documentation Record for High-Risk AI Systems" if language == "en" else "Registre de Conformité AI Act"
34
  pdf.cell(0, 15, title, ln=True, align='C')
35
- pdf.ln(10)
36
 
37
- # Subtitle
38
- pdf.set_font("Arial", 'I', 12)
39
  pdf.set_text_color(90, 90, 90)
40
- subtitle = f"Generated on {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
41
- pdf.cell(0, 10, subtitle, ln=True, align='C')
42
- pdf.ln(5)
 
 
43
 
44
  # Reset style for body
45
  pdf.set_font("Arial", '', 12)
46
  pdf.set_text_color(0, 0, 0)
47
 
48
- # Parse and format sections
49
  for line in text.strip().split('\n'):
50
  line = line.strip()
51
  if line.startswith("## "):
@@ -58,15 +50,15 @@ def export_text_to_pdf(text, output_path=None, language="fr"):
58
  pdf.set_font("Arial", '', 12)
59
  pdf.set_text_color(0, 0, 0)
60
  elif line.startswith("- **"):
61
- key_value = re.match(r"- \*\*(.+?)\*\*: (.+)", line)
62
- if key_value:
63
- label, answer = key_value.groups()
64
  pdf.set_font("Arial", 'B', 12)
65
  pdf.cell(0, 10, f"{label}:", ln=True)
66
  pdf.set_font("Arial", '', 12)
67
- pdf.multi_cell(0, 10, f"{answer}")
68
  pdf.ln(2)
69
- elif line.strip() == "---":
70
  pdf.line(10, pdf.get_y(), 200, pdf.get_y())
71
  pdf.ln(5)
72
  else:
@@ -76,7 +68,7 @@ def export_text_to_pdf(text, output_path=None, language="fr"):
76
  pdf.output(output_path)
77
  return output_path
78
 
79
- # === Sequential Questions ===
80
  QUESTIONS = [
81
  ("organization_name", "What is the name of your organization?"),
82
  ("responsible_person", "Who is responsible for this AI system?"),
@@ -93,9 +85,7 @@ QUESTIONS = [
93
  ("compliance_contact", "Who is the contact person for compliance (email or name)?")
94
  ]
95
 
96
- RESPONSES = {}
97
-
98
- # === Interactive Collection Flow ===
99
  def step_by_step_agent(user_input, state):
100
  if state is None:
101
  state = {"step": 0, "answers": {}}
@@ -110,7 +100,7 @@ def step_by_step_agent(user_input, state):
110
  if step < len(QUESTIONS):
111
  next_question = QUESTIONS[step][1]
112
  state["step"] += 1
113
- return next_question, state, None # Ensure return matches expected 3 outputs
114
 
115
  filled_template = f"""
116
  # AI Act Compliance Register
@@ -140,14 +130,11 @@ def step_by_step_agent(user_input, state):
140
  Generated by AI Act Assistant.
141
  """
142
 
143
-
144
-
145
  try:
146
  detected_lang = detect(filled_template)
147
  except:
148
  detected_lang = "en"
149
 
150
- flag = "🇬🇧" if detected_lang == "en" else "🇫🇷"
151
  # Save to CSV
152
  csv_file = "ai_act_registers.csv"
153
  fieldnames = [key for key, _ in QUESTIONS] + ["timestamp"]
@@ -160,44 +147,43 @@ Generated by AI Act Assistant.
160
  writer.writeheader()
161
  writer.writerow(row_data)
162
 
163
- pdf_path = export_text_to_pdf(filled_template, language=detected_lang)
164
- return f"""{flag} Language detected: {detected_lang.upper()}
165
- ✅ All answers received. Your PDF is ready below:
166
- 👉 Click the download button to save your AI Act compliance register.""", {"done": True, "pdf": pdf_path}, pdf_path
 
 
 
 
 
 
 
 
167
 
168
- # === UI for Step-by-Step Form ===
169
  def launch_step_by_step_ui():
170
- with gr.Blocks(fill_height=True) as demo:
171
- initial_question = QUESTIONS[0][1]
172
- initial_message = gr.ChatMessage(role="assistant", content="""
173
- 👋 Welcome! I will guide you through the AI Act compliance form.
174
- Let's begin with a few questions to generate your compliance register.
175
-
176
- What is the name of your organization?
177
- """)
178
- stored_messages = [initial_message]
179
- chatbot = gr.Chatbot(type="messages", value=stored_messages)
180
  msg = gr.Textbox(label="Your answer")
181
  state = gr.State()
182
  file_output = gr.File(label="Download PDF", visible=True)
183
- restart_button = gr.Button("🔁 Restart")
184
 
185
- def chat_logic(user_msg, state):
186
- reply, updated_state, file_path = step_by_step_agent(user_msg, state)
187
- messages = [gr.ChatMessage(role="user", content=user_msg)]
188
 
189
- if isinstance(reply, str):
 
 
 
190
  messages.append(gr.ChatMessage(role="assistant", content=reply))
 
191
 
192
- if not file_path or not os.path.isfile(file_path):
193
- file_path = None
194
- return messages, updated_state, file_path
195
-
196
- def restart_conversation():
197
- return [initial_message], {"step": 0, "answers": {}}, None
198
 
199
  msg.submit(chat_logic, [msg, state], [chatbot, state, file_output])
200
- restart_button.click(restart_conversation, outputs=[chatbot, state, file_output])
201
 
202
  demo.launch()
203
 
@@ -205,5 +191,4 @@ def get_questions():
205
  return QUESTIONS
206
 
207
  def run_tool():
208
- return launch_step_by_step_ui()
209
-
 
2
  # coding=utf-8
3
  import csv
4
  import datetime
 
5
  import os
6
  import re
 
 
 
 
 
 
 
 
 
7
  from fpdf import FPDF
8
+ import gradio as gr
9
  from langdetect import detect
10
 
11
+ # === PDF Export Function with Metadata ===
12
+ def export_text_to_pdf(text, output_path=None, language="fr", metadata=None):
13
  if output_path is None:
14
  timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
15
  output_path = f"ai_act_register_{timestamp}.pdf"
 
23
  pdf.set_text_color(0, 51, 102)
24
  title = "Documentation Record for High-Risk AI Systems" if language == "en" else "Registre de Conformité AI Act"
25
  pdf.cell(0, 15, title, ln=True, align='C')
26
+ pdf.ln(8)
27
 
28
+ # Subtitle / Metadata
29
+ pdf.set_font("Arial", '', 12)
30
  pdf.set_text_color(90, 90, 90)
31
+ if metadata:
32
+ pdf.multi_cell(0, 10, f"🏢 Organization: {metadata.get('organization_name', 'N/A')}")
33
+ pdf.multi_cell(0, 10, f"👤 Completed by: {metadata.get('responsible_person', 'N/A')}")
34
+ pdf.multi_cell(0, 10, f"🕒 Completion Date: {metadata.get('timestamp', datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))}")
35
+ pdf.ln(5)
36
 
37
  # Reset style for body
38
  pdf.set_font("Arial", '', 12)
39
  pdf.set_text_color(0, 0, 0)
40
 
 
41
  for line in text.strip().split('\n'):
42
  line = line.strip()
43
  if line.startswith("## "):
 
50
  pdf.set_font("Arial", '', 12)
51
  pdf.set_text_color(0, 0, 0)
52
  elif line.startswith("- **"):
53
+ match = re.match(r"- \*\*(.+?)\*\*: (.+)", line)
54
+ if match:
55
+ label, answer = match.groups()
56
  pdf.set_font("Arial", 'B', 12)
57
  pdf.cell(0, 10, f"{label}:", ln=True)
58
  pdf.set_font("Arial", '', 12)
59
+ pdf.multi_cell(0, 10, answer)
60
  pdf.ln(2)
61
+ elif line == "---":
62
  pdf.line(10, pdf.get_y(), 200, pdf.get_y())
63
  pdf.ln(5)
64
  else:
 
68
  pdf.output(output_path)
69
  return output_path
70
 
71
+ # === Questions ===
72
  QUESTIONS = [
73
  ("organization_name", "What is the name of your organization?"),
74
  ("responsible_person", "Who is responsible for this AI system?"),
 
85
  ("compliance_contact", "Who is the contact person for compliance (email or name)?")
86
  ]
87
 
88
+ # === Agent Logic ===
 
 
89
  def step_by_step_agent(user_input, state):
90
  if state is None:
91
  state = {"step": 0, "answers": {}}
 
100
  if step < len(QUESTIONS):
101
  next_question = QUESTIONS[step][1]
102
  state["step"] += 1
103
+ return next_question, state, None
104
 
105
  filled_template = f"""
106
  # AI Act Compliance Register
 
130
  Generated by AI Act Assistant.
131
  """
132
 
 
 
133
  try:
134
  detected_lang = detect(filled_template)
135
  except:
136
  detected_lang = "en"
137
 
 
138
  # Save to CSV
139
  csv_file = "ai_act_registers.csv"
140
  fieldnames = [key for key, _ in QUESTIONS] + ["timestamp"]
 
147
  writer.writeheader()
148
  writer.writerow(row_data)
149
 
150
+ # PDF Export
151
+ pdf_path = export_text_to_pdf(
152
+ filled_template,
153
+ language=detected_lang,
154
+ metadata={
155
+ "organization_name": answers.get("organization_name", ""),
156
+ "responsible_person": answers.get("responsible_person", ""),
157
+ "timestamp": datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
158
+ }
159
+ )
160
+
161
+ return f"✅ All answers received. Your PDF is ready below:", {"done": True, "pdf": pdf_path}, pdf_path
162
 
163
+ # === Gradio UI ===
164
  def launch_step_by_step_ui():
165
+ with gr.Blocks(title="AI Act Compliance Register") as demo:
166
+ chatbot = gr.Chatbot(label="📘 AI Act Assistant", type="messages")
 
 
 
 
 
 
 
 
167
  msg = gr.Textbox(label="Your answer")
168
  state = gr.State()
169
  file_output = gr.File(label="Download PDF", visible=True)
170
+ restart_btn = gr.Button("🔁 Restart")
171
 
172
+ initial_q = QUESTIONS[0][1]
173
+ chatbot.value = [gr.ChatMessage(role="assistant", content=f"👋 Welcome! Let's begin.\n\n{initial_q}")]
 
174
 
175
+ def chat_logic(user_msg, state_in):
176
+ reply, state_out, file_path = step_by_step_agent(user_msg, state_in)
177
+ messages = [gr.ChatMessage(role="user", content=user_msg)]
178
+ if reply:
179
  messages.append(gr.ChatMessage(role="assistant", content=reply))
180
+ return messages, state_out, file_path
181
 
182
+ def restart():
183
+ return [gr.ChatMessage(role="assistant", content=initial_q)], {"step": 0, "answers": {}}, None
 
 
 
 
184
 
185
  msg.submit(chat_logic, [msg, state], [chatbot, state, file_output])
186
+ restart_btn.click(restart, outputs=[chatbot, state, file_output])
187
 
188
  demo.launch()
189
 
 
191
  return QUESTIONS
192
 
193
  def run_tool():
194
+ launch_step_by_step_ui()