File size: 3,592 Bytes
26215e2
2497eb4
b839a2b
 
 
 
 
 
 
26215e2
2497eb4
b839a2b
e73e89e
b839a2b
 
 
 
2497eb4
 
b839a2b
2497eb4
b839a2b
 
 
2497eb4
 
b839a2b
 
 
2497eb4
 
b839a2b
2497eb4
b839a2b
2497eb4
 
 
 
 
 
 
 
 
b839a2b
2497eb4
b839a2b
 
 
 
 
 
fc302aa
2497eb4
 
b839a2b
2497eb4
b839a2b
e73e89e
26215e2
2497eb4
e73e89e
 
26215e2
2497eb4
e73e89e
2497eb4
 
 
 
b839a2b
 
 
2497eb4
 
fc302aa
 
2497eb4
fc302aa
2497eb4
26215e2
fc302aa
 
26215e2
e73e89e
26215e2
2497eb4
 
 
 
b839a2b
2497eb4
 
b839a2b
2497eb4
 
fc302aa
2497eb4
e73e89e
2497eb4
b839a2b
26215e2
2497eb4
e73e89e
b839a2b
2497eb4
 
e73e89e
2497eb4
26215e2
e73e89e
 
2497eb4
b839a2b
fc302aa
26215e2
e73e89e
 
2497eb4
b839a2b
fc302aa
26215e2
fc302aa
 
e73e89e
f4c8195
fc302aa
 
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
import gradio as gr
import tempfile

from intelligence_pipeline import (
    analyze_threat,
    translate_and_explain,
)
from safety_classifier import safety_check


def handle_threat_intel(message, files):
    base = analyze_threat(message or "")
    if files:
        file_names = ", ".join(f.name for f in files)
        base += f"\n\nAttached files: {file_names}"
    return base


def handle_translation(message, files):
    base = translate_and_explain(message or "")
    if files:
        base += "\n\nNote: Translation mode currently ignores attached files."
    return base


def handle_marketplace_watch(message, files):
    out = f"[Marketplace Watch] Monitoring: {message or ''}"
    if files:
        out += " | attached logs available"
    return out


def handle_analyst_tools(message, files):
    return "[Analyst Tools] " + (message or "")


MODE_ROUTER = {
    "Threat Intel": handle_threat_intel,
    "Translation": handle_translation,
    "Marketplace Watch": handle_marketplace_watch,
    "Analyst Tools": handle_analyst_tools,
}


def process_message(message, files, history, mode):
    text = message or ""

    safety = safety_check(text)
    if safety["blocked"]:
        response = "⚠️ Safety Block: " + safety["reason"]
        history = history + [(f"{mode}: {text}", response)]
        return history, history

    handler = MODE_ROUTER.get(mode, handle_threat_intel)
    response = handler(text, files)

    history = history + [(f"{mode}: {text}", response)]
    return history, history


def clear_chat():
    return [], []


def download_chat(history):
    if not history:
        content = "No conversation yet.\n"
    else:
        lines = []
        for u, s in history:
            lines.append(f"[User]: {u}")
            lines.append(f"[System]: {s}\n")
        content = "\n".join(lines)

    tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".txt")
    with open(tmp.name, "w", encoding="utf-8") as f:
        f.write(content)
    return tmp.name


with gr.Blocks(title="Threat Landscape Intelligence Console") as demo:
    gr.Markdown("## 🛰 APJ Threat Intelligence Console")

    chat_state = gr.State([])

    mode = gr.Radio(
        ["Threat Intel", "Translation", "Marketplace Watch", "Analyst Tools"],
        value="Threat Intel",
        label="Mode",
        interactive=True,
    )

    chat = gr.Chatbot(label="Dialogue", height=430)

    with gr.Accordion("Attachments & Utilities", open=False):
        file_input = gr.File(label="Upload files", file_count="multiple")
        with gr.Row(variant="compact"):
            clear_btn = gr.Button("Clear Chat", variant="secondary")
            download_btn = gr.Button("Download Transcript", variant="secondary")
        download_file = gr.File(label="Transcript", interactive=False)

    with gr.Row(variant="compact"):
        user_input = gr.Textbox(
            placeholder="Enter text…",
            label="",
            scale=5
        )
        send_btn = gr.Button("Send", variant="primary", scale=1)

    send_btn.click(
        fn=process_message,
        inputs=[user_input, file_input, chat_state, mode],
        outputs=[chat, chat_state],
    ).then(lambda: "", None, user_input)

    user_input.submit(
        fn=process_message,
        inputs=[user_input, file_input, chat_state, mode],
        outputs=[chat, chat_state],
    ).then(lambda: "", None, user_input)

    clear_btn.click(fn=clear_chat, outputs=[chat, chat_state])
    download_btn.click(fn=download_chat, inputs=chat_state, outputs=download_file)


if __name__ == "__main__":
    demo.launch()