File size: 11,152 Bytes
6b32a83
e0e3c77
1aa78bb
c5f6e65
6ea1e62
c5f6e65
30f2036
6ea1e62
8412cb4
95e51a1
c14df9d
b38b02c
19f9d91
33943d3
b0a4524
 
 
8412cb4
 
32c4bd7
 
2729068
32c4bd7
 
 
d26fc94
 
 
9dd57a8
 
 
d26fc94
 
9dd57a8
 
 
d26fc94
 
9dd57a8
 
d26fc94
9dd57a8
 
 
 
 
 
 
 
30f2036
 
 
 
 
 
 
 
 
 
c6d3213
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7f1deed
 
 
 
 
 
 
 
 
 
56a9609
 
 
 
 
 
 
 
 
8412cb4
d2e1729
8412cb4
64cc4b0
8412cb4
c5f6e65
 
8412cb4
fd6b4ee
8412cb4
 
 
fd6b4ee
 
 
 
 
 
 
 
 
 
 
 
8412cb4
 
610ad2a
 
 
5f2df58
610ad2a
 
 
8412cb4
 
 
 
 
 
 
 
 
 
 
 
 
6ea1e62
8412cb4
 
 
 
 
95e51a1
 
8412cb4
 
6ea1e62
8412cb4
 
 
 
6ea1e62
 
 
 
95e51a1
6ea1e62
cf3105e
 
8412cb4
6ea1e62
8412cb4
cf3105e
8412cb4
ac70e9a
8412cb4
2729068
 
 
2914f64
2729068
 
 
 
 
8412cb4
 
 
81a6310
cf3105e
8412cb4
64cc4b0
cf3105e
 
8412cb4
e612c9d
81a6310
 
 
 
 
8f68190
 
 
 
81a6310
 
8f68190
 
 
 
81a6310
 
 
7ad3ec8
0781cb9
f15da98
 
 
5d9338d
df8e74e
ac70e9a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8412cb4
1f27b80
42db30f
 
 
1f27b80
 
 
8412cb4
81a6310
95e51a1
8412cb4
 
81a6310
8412cb4
ac70e9a
8412cb4
5d9338d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
import gradio as gr
from fpdf import FPDF
from langdetect import detect
import time
import importlib

# === Map document choices to modules ===
DOCUMENT_TO_MODULE = {
    "AI Act": {
        "Compliance Register": "tools.ai_act_generator",
        "High-Risk System Record": "tools.high_risk_ai_register",
        "Technical Documentation Template": "tools.ai_technical_doc",
        "Post-Market Monitoring Plan": "tools.post_market_monitoring",
        "Risk-Management Plan": "tools.risk_management_plan",
        "Data Governance Record": "tools.data_governance_record",
        "Human Oversight Strategy (Art. 14)": "tools.human_oversight_strategy",
        "Corrective Action Log": "tools.corrective_action_log"
    },
    "GDPR": {
        "Data Processing Record": "tools.gdpr_data_record",
        "DPIA (Data Protection Impact Assessment)": "tools.gdpr_dpia",
        "Data Breach Notification Log": "tools.gdpr_breach_log",
        "Subject Access Request Record": "tools.gdpr_sar_log",
        "Consent Management Log": "tools.gdpr_consent_log",
        "Data Processor Agreements": "tools.gdpr_dpa_log"
    },
    "NIS2": {
        "Access Control Log": "tools.nis2_access_control_log",
        "Asset Inventory": "tools.nis2_asset_inventory",
        "Backup & Recovery Log": "tools.nis2_backup_recovery_log",
        "Business Continuity Plan": "tools.nis2_business_continuity",
        "Compliance Audit Log": "tools.nis2_compliance_audit_log",
        "Data Encryption Inventory": "tools.nis2_data_encryption_inventory",
        "Disaster Recovery Plan": "tools.nis2_disaster_recovery_plan",
        "Incident Communication Plan": "tools.nis2_incident_communication",
        "Incident Response Log": "tools.nis2_incident_log",
        "Logging & Monitoring Policy": "tools.nis2_logging_monitoring_policy",
        "Network Architecture Diagram Log": "tools.nis2_network_architecture_log",
        "Penetration Test Summary": "tools.nis2_penetration_test_summary",
        "Physical Security Checklist": "tools.nis2_physical_security_checklist",
        "Risk Assessment Matrix": "tools.nis2_risk_assessment_matrix",
        "Risk Register": "tools.nis2_risk_register",
        "Security Audit Record": "tools.nis2_security_audit",
        "Security Testing Strategy": "tools.nis2_security_testing_strategy",
        "Security Awareness Training Record": "tools.nis2_security_training_record",
        "Supply Chain Risk Record": "tools.nis2_supply_chain_risk",
        "System Testing Record": "tools.nis2_system_testing",
        "Third-Party Access Review": "tools.nis2_third_party_access_review",
        "Vulnerability Management Log": "tools.nis2_vulnerability_log"
    },
    "DORA": {
        "Third-Party ICT Risk Register": "tools.nis2_third_party_access_review",
        "ICT Asset Inventory": "tools.nis2_asset_inventory",
        "Incident Reporting Log": "tools.nis2_incident_log",
        "Risk Register": "tools.nis2_risk_register",
        "Backup & Recovery": "tools.nis2_backup_recovery_log",
        "Penetration Testing Summary": "tools.nis2_penetration_test_summary",
        "Disaster Recovery Plan": "tools.nis2_disaster_recovery_plan",
        "Security Testing Strategy": "tools.nis2_security_testing_strategy",
        "Backup Strategy Summary": "tools.dora_backup_strategy_summary",
        "Capacity Management Log": "tools.dora_capacity_management_log",
        "Cloud Resilience Assessment": "tools.dora_cloud_resilience_assessment",
        "Cloud Service Usage Log": "tools.dora_cloud_service_usage_log",
        "Communication Tree (Crisis)": "tools.dora_communication_tree",
        "Critical Function Inventory": "tools.dora_critical_function_inventory",
        "Data Integrity Strategy": "tools.dora_data_integrity_strategy",
        "Data Loss Prevention": "tools.dora_data_loss_prevention",
        "Encryption Strategy": "tools.dora_encryption_strategy",
        "ICT Asset Log": "tools.dora_ict_asset_log",
        "ICT Asset Register": "tools.dora_ict_asset_register",
        "Incident Notification Log": "tools.dora_incident_notification_log",
        "Network Resilience Assessment": "tools.dora_network_resilience_assessment",
        "Remote Access Policy": "tools.dora_remote_access_policy",
        "Risk Management Policy": "tools.dora_risk_management_policy",
        "Simulation Test Log": "tools.dora_simulation_test_log",
        "Third-Party Dependency Map": "tools.dora_third_party_dependency_map",
        "Third-Party Dependency Register": "tools.dora_third_party_dependency_register",
        "Third-Party Log": "tools.dora_third_party_log",
        "Third-Party Mapping": "tools.dora_third_party_mapping"
    },
        "DMA": {
        "Gatekeeper Service Log": "tools.dma_gatekeeper_service_log",
        "User Consent Overview": "tools.dma_user_consent_overview",
        "Interoperability Compliance Report": "tools.dma_interoperability_report",
        "Data Sharing Record": "tools.dma_data_sharing_record",
        "Complaint Handling Log": "tools.dma_complaint_log",
        "Self-Assessment Declaration": "tools.dma_self_assessment",
        "Third-Party Access Request Register": "tools.dma_third_party_access_register",
        "Transparency Obligation Record": "tools.dma_transparency_log"
    },
        "DSA": {
        "Content Moderation Log": "tools.dsa_content_moderation_log",
        "Transparency Report": "tools.dsa_transparency_report",
        "Complaint Handling Register": "tools.dsa_complaint_handling_log",
        "Risk Mitigation Measures": "tools.dsa_risk_mitigation_log",
        "Ad Targeting Policy Log": "tools.dsa_ad_targeting_log",
        "Trusted Flaggers Log": "tools.dsa_trusted_flaggers_log"
    }   
}


# === PDF Export Function ===
def export_pdf(title, answers, lang="en"):
    pdf = FPDF()
    pdf.add_page()
    pdf.set_auto_page_break(auto=True, margin=15)

    pdf.set_font("Arial", 'B', 16)
    pdf.set_text_color(0, 51, 102)
    pdf.cell(0, 10, title, ln=True, align='C')
    pdf.ln(8)

    company = answers.get("What is the name of your organization?", "N/A")
    name = answers.get("What is your name?", "N/A")
    role = answers.get("What is your role?", "N/A")
    timestamp = time.strftime("%Y-%m-%d %H:%M:%S")

    pdf.set_font("Arial", 'I', 11)
    pdf.set_text_color(80, 80, 80)
    pdf.cell(0, 8, f"Organization: {company}", ln=True, align='C')
    pdf.cell(0, 8, f"Completed by: {name} ({role})", ln=True, align='C')
    pdf.cell(0, 8, f"Timestamp: {timestamp}", ln=True, align='C')
    pdf.ln(10)

    # Add a draft disclaimer
    pdf.set_font("Arial", 'B', 12)
    pdf.set_text_color(200, 0, 0)  # Red color
    pdf.multi_cell(0, 10, "DRAFT: This document is a draft generated by an AI assistant.\nIt is not legal advice and should be reviewed by a qualified professional.")
    pdf.ln(10)


    pdf.set_font("Arial", '', 12)
    pdf.set_text_color(0, 0, 0)
    for label, value in answers.items():
        pdf.set_font("Arial", 'B', 12)
        pdf.multi_cell(0, 10, f"{label}:", align='L')
        pdf.set_font("Arial", '', 12)
        pdf.multi_cell(0, 10, value)
        pdf.ln(5)

    filename = f"{title.replace(' ', '_')}_{int(time.time())}.pdf"
    pdf.output(filename)
    return filename

# === State Memory ===
conversation_state = {
    "step": 0,
    "questions": [],
    "answers": {},
    "title": "",
    "lang": "en",
    "tool": None
}

# === Load Tool Dynamically ===
def start_conversation(reg, doc):
    conversation_state["step"] = 0
    conversation_state["answers"] = {}
    conversation_state["title"] = f"{reg} - {doc}"

    module_path = DOCUMENT_TO_MODULE[reg][doc]
    module = importlib.import_module(module_path)
    conversation_state["questions"] = module.get_questions()
    conversation_state["tool"] = module

    first_question = conversation_state["questions"][0][1]
    return [{"role": "assistant", "content": f"📋 {first_question}"}]

# === Continue Chat ===
def continue_conversation(user_input):
    messages = [{"role": "user", "content": user_input}]
    step = conversation_state["step"]

    if step < len(conversation_state["questions"]):
        key, question = conversation_state["questions"][step]
        conversation_state["answers"][question] = user_input
        conversation_state["step"] += 1

        try:
            if user_input and len(user_input.strip()) > 3:
                conversation_state["lang"] = detect(user_input)
        except:
            conversation_state["lang"] = "en"

    if conversation_state["step"] < len(conversation_state["questions"]):
        next_question = conversation_state["questions"][conversation_state["step"]][1]
        messages.append({"role": "assistant", "content": f"🧠 {next_question}"})
        return messages, None
    else:
        pdf_path = export_pdf(conversation_state["title"], conversation_state["answers"], lang=conversation_state["lang"])
        messages.append({"role": "assistant", "content": "✅ Done! Your document is ready to download."})
        return messages, pdf_path

# === Gradio Interface ===
with gr.Blocks(
    title="Regulatory Compliance Generator",
    css="""
    footer, 
    a[href*="gradio.app"],
    a[href*="huggingface.co"] {
        display: none !important;
    }

    button[aria-label="Share"],
    button[title="Share"],
    button[data-testid="share-button"] {
        pointer-events: none !important;
        opacity: 0.4 !important;
        cursor: default !important;
    }
    """
) as demo:
    gr.Markdown("""
    ### 🔒 GDPR Notice  
    This assistant does not store any personal data.  
    All responses are processed temporarily to generate your document.  
    You are responsible for the accuracy and legality of the information submitted.
    """)

    with gr.Row():
        reg_dropdown = gr.Dropdown(
            choices=list(DOCUMENT_TO_MODULE.keys()),
            label="Select Regulation",
            value=None,
            interactive=True,
            info="-- Please choose a regulation --"
        )
        doc_dropdown = gr.Dropdown(
            label="Select Document Type",
            choices=[],
            value=None,
            interactive=True,
            info="-- Select a document after choosing a regulation --"
        )

    def update_doc_dropdown(selected_reg):
        if selected_reg in DOCUMENT_TO_MODULE:
            return gr.update(choices=list(DOCUMENT_TO_MODULE[selected_reg].keys()), value=None)
        return gr.update(choices=[], value=None)

    reg_dropdown.change(update_doc_dropdown, inputs=reg_dropdown, outputs=doc_dropdown)

    start_btn = gr.Button("🚀 Start")
    chatbox = gr.Chatbot(label="🧑‍⚖️ Legalbot", value=[], type="messages", elem_classes=["chatbot"])
    user_input = gr.Textbox(label="Your answer", placeholder="Type your answer and press Enter")
    pdf_output = gr.File(label="Download PDF", visible=True)

    start_btn.click(start_conversation, inputs=[reg_dropdown, doc_dropdown], outputs=chatbox)
    user_input.submit(continue_conversation, inputs=user_input, outputs=[chatbox, pdf_output])
    user_input.submit(lambda: "", None, user_input)

demo.launch()