File size: 4,979 Bytes
653c010
 
 
 
bd8d91b
 
 
 
653c010
 
 
 
bd8d91b
 
 
 
 
 
 
653c010
 
bd8d91b
 
 
 
 
653c010
 
 
 
 
 
 
 
 
 
 
bd8d91b
 
 
 
653c010
bd8d91b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
653c010
bd8d91b
 
 
653c010
 
bd8d91b
 
 
 
 
 
 
 
 
 
653c010
 
bd8d91b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
653c010
 
 
 
 
 
 
 
 
bd8d91b
 
653c010
 
 
 
 
 
bd8d91b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6b00b99
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
#!/usr/bin/env python
# coding=utf-8
import datetime
import re
from fpdf import FPDF
from langdetect import detect
import gradio as gr

from tools.common import prepend_metadata_questions  # ✅ Import shared metadata logic

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

    pdf = FPDF()
    pdf.add_page()
    pdf.set_auto_page_break(auto=True, margin=15)

    # Title
    pdf.set_font("Arial", 'B', 16)
    pdf.set_text_color(0, 51, 102)
    title = "Human Oversight Strategy (Art. 14)" if language == "en" else "Stratégie de Supervision Humaine"
    pdf.cell(0, 15, title, ln=True, align='C')
    pdf.ln(10)

    # Metadata block
    if metadata:
        pdf.set_font("Arial", '', 12)
        pdf.set_text_color(90, 90, 90)
        pdf.multi_cell(0, 10, f"Organization: {metadata.get('organization', 'N/A')}")
        pdf.multi_cell(0, 10, f"Completed by: {metadata.get('completed_by', 'N/A')} ({metadata.get('role', 'N/A')})")
        pdf.multi_cell(0, 10, f"Timestamp: {metadata.get('timestamp', 'N/A')}")
        pdf.ln(5)

    # Content 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)
        else:
            pdf.multi_cell(0, 10, line)

    pdf.output(output_path)
    return output_path

# === Base Questions ===
BASE_QUESTIONS = [
    ("system_name", "What is the name of the AI system?"),
    ("oversight_roles", "Who is responsible for human oversight?"),
    ("oversight_tasks", "What are their oversight responsibilities?"),
    ("intervention_methods", "How can they intervene in the system?"),
    ("training", "What training is provided to oversight personnel?"),
    ("monitoring_tools", "What tools help humans supervise the system?"),
    ("limitations", "What are known limitations of human control?"),
    ("escalation", "What is the escalation protocol for risks?")
]

QUESTIONS = prepend_metadata_questions(BASE_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):
            question = QUESTIONS[step][1]
            state["step"] += 1
            return question, state, None

        content = "\n".join([f"- **{label}**: {answers.get(key, '')}" for key, label in QUESTIONS])
        lang = detect(content)

        metadata = {
            "organization": answers.get("organization_name", "N/A"),
            "completed_by": answers.get("user_name", "N/A"),
            "role": answers.get("user_role", "N/A"),
            "timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        }

        pdf_path = export_text_to_pdf(content, metadata=metadata, language=lang)
        return "✅ Strategy ready below!", {"done": True}, pdf_path

    with gr.Blocks(title="Human Oversight Strategy Tool") as demo:
        chatbot = gr.Chatbot(
            label="👁️ Human Oversight 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")
        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)