File size: 5,156 Bytes
5ac90b6
 
8996dc4
5ac90b6
 
 
54be9b0
8996dc4
 
5ac90b6
 
8996dc4
5ac90b6
 
 
 
 
 
 
 
 
 
 
 
8996dc4
 
 
 
 
 
 
 
 
 
 
 
 
5ac90b6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8996dc4
5ac90b6
 
 
 
8996dc4
5ac90b6
 
 
 
 
 
 
 
 
 
 
 
 
 
8996dc4
 
5ac90b6
 
54be9b0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8996dc4
 
54be9b0
8996dc4
54be9b0
 
909c638
8996dc4
 
 
 
 
54be9b0
 
909c638
54be9b0
 
 
 
 
 
 
 
 
 
 
 
 
 
909c638
5615a48
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
# tools/ai_technical_doc.py
import datetime
import os
import re
from fpdf import FPDF
from langdetect import detect
import gradio as gr

from tools.common import prepend_metadata_questions  # Shared metadata question helper

# === PDF Export Function ===
def export_text_to_pdf(text, answers, output_path=None, language="en"):
    if output_path is None:
        timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        output_path = f"technical_documentation_{timestamp}.pdf"

    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)
    title = "Technical Documentation - AI Act (Art. 11)" if language == "en" else "Documentation Technique - AI Act"
    pdf.cell(0, 15, title, ln=True, align='C')
    pdf.ln(5)

    # Metadata under title
    pdf.set_font("Arial", 'I', 11)
    pdf.set_text_color(80, 80, 80)
    name = answers.get("user_name", "N/A")
    role = answers.get("user_role", "N/A")
    org = answers.get("organization_name", "N/A")
    timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    pdf.multi_cell(0, 10, f"Completed by {name} ({role}) at {org} on {timestamp}", align="C")
    pdf.ln(5)

    # Main body
    pdf.set_font("Arial", '', 12)
    pdf.set_text_color(0, 0, 0)
    for line in text.strip().split('\n'):
        line = line.strip()
        if line.startswith("## "):
            section = line.replace("## ", "").strip()
            pdf.set_font("Arial", 'B', 13)
            pdf.set_text_color(30, 30, 120)
            pdf.ln(8)
            pdf.cell(0, 10, section, ln=True)
            pdf.set_font("Arial", '', 12)
            pdf.set_text_color(0, 0, 0)
        elif line.startswith("- **"):
            match = re.match(r"- \*\*(.+?)\*\*: (.+)", line)
            if match:
                label, value = match.groups()
                pdf.set_font("Arial", 'B', 12)
                pdf.cell(0, 10, f"{label}:", ln=True)
                pdf.set_font("Arial", '', 12)
                pdf.multi_cell(0, 10, value)
        elif line == "---":
            pdf.line(10, pdf.get_y(), 200, pdf.get_y())
            pdf.ln(5)
        else:
            pdf.multi_cell(0, 10, line)

    pdf.output(output_path)
    return output_path

# === Questions ===
CORE_QUESTIONS = [
    ("system_name", "What is the name of your AI system?"),
    ("provider", "Who is the provider or developer of the system?"),
    ("intended_purpose", "What is the intended purpose of the system?"),
    ("architecture", "Describe the system architecture."),
    ("training_data", "What kind of training data is used?"),
    ("testing_methodology", "How was the system tested and validated?"),
    ("performance_metrics", "What are the system's performance metrics?"),
    ("risk_management", "What risk management measures were taken?"),
    ("cybersecurity", "What cybersecurity measures are in place?"),
    ("human_oversight", "How is human oversight implemented?"),
    ("versioning", "How is version control maintained?"),
    ("recordkeeping", "How are logs and records maintained?")
]

QUESTIONS = prepend_metadata_questions(CORE_QUESTIONS)

def get_questions():
    return QUESTIONS

def run_tool():
    state = {"step": 0, "answers": {}}

    def step_by_step_agent(user_input, state):
        step = state["step"]
        answers = state["answers"]

        if step > 0:
            key, _ = QUESTIONS[step - 1]
            answers[key] = user_input

        if step < len(QUESTIONS):
            next_question = QUESTIONS[step][1]
            state["step"] += 1
            return next_question, state, None

        # Final content for PDF
        content = "\n".join([f"- **{label}**: {answers.get(key, '')}" for key, label in QUESTIONS if key not in ["user_name", "user_role", "organization_name"]])
        detected_lang = detect(content)
        pdf_path = export_text_to_pdf(content, answers, language=detected_lang)
        return "✅ Completed. Download your documentation below.", {"done": True}, pdf_path

    with gr.Blocks(title="AI Technical Documentation Tool") as demo:
        chatbot = gr.Chatbot(
            label="🧠 Technical Doc Assistant",
            value=[{"role": "assistant", "content": QUESTIONS[0][1]}],
            type="messages"
        )
        msg = gr.Textbox(label="Your answer")
        state_var = gr.State(state)
        file_output = gr.File(label="Download PDF", visible=True)
        reset_btn = gr.Button("🔁 Restart")

        def chat_logic(msg_in, state_in):
            reply, updated_state, file = step_by_step_agent(msg_in, state_in)
            messages = [{"role": "user", "content": msg_in}]
            if reply:
                messages.append({"role": "assistant", "content": reply})
            return messages, updated_state, file

        def reset():
            return [{"role": "assistant", "content": QUESTIONS[0][1]}], {"step": 0, "answers": {}}, None

        msg.submit(chat_logic, [msg, state_var], [chatbot, state_var, file_output])
        reset_btn.click(reset, outputs=[chatbot, state_var, file_output])

    demo.launch(show_api=False)