S-Dreamer commited on
Commit
e00fc58
·
verified ·
1 Parent(s): 866d1e1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +156 -1
app.py CHANGED
@@ -126,4 +126,159 @@ def inject_osint_context(history, task_result: Dict[str, Any]):
126
  """
127
  pretty = json.dumps(task_result, indent=2, default=str)
128
  blob = f"""
129
- ### OSINT Result Injected:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  """
127
  pretty = json.dumps(task_result, indent=2, default=str)
128
  blob = f"""
129
+ ### OSINT Result Injected:
130
+
131
+ {pretty}
132
+
133
+ """
134
+
135
+ history.append({"role": "system", "content": blob})
136
+ return history
137
+
138
+
139
+ # ---------------------------------------------------------------------
140
+ # Dashboard callbacks (Mode B)
141
+ # ---------------------------------------------------------------------
142
+
143
+ def ui_lookup_ip(ip, enrich, mitre):
144
+ raw = call_task("lookup_ip", {"ip": ip, "enrich": enrich, "map_mitre": mitre})
145
+ normal = format_result_for_ui(raw)
146
+ return normal["summary"], normal["markdown"], normal["json"], normal["mitre"], normal["stix"], raw
147
+
148
+
149
+ def ui_lookup_domain(domain, enrich, mitre):
150
+ raw = call_task("lookup_domain", {"domain": domain, "enrich": enrich, "map_mitre": mitre})
151
+ normal = format_result_for_ui(raw)
152
+ return normal["summary"], normal["markdown"], normal["json"], normal["mitre"], normal["stix"], raw
153
+
154
+
155
+ def ui_lookup_hash(h, ht, enrich, mitre):
156
+ raw = call_task("lookup_hash", {"hash": h, "hash_type": ht, "enrich": enrich, "map_mitre": mitre})
157
+ normal = format_result_for_ui(raw)
158
+ return normal["summary"], normal["markdown"], normal["json"], normal["mitre"], normal["stix"], raw
159
+
160
+
161
+ def ui_correlate_iocs(iocs):
162
+ parsed = [l.strip() for l in iocs.splitlines() if l.strip()]
163
+ raw = call_task("correlate_iocs", {"iocs": parsed})
164
+ normal = format_result_for_ui(raw)
165
+ return normal["summary"], normal["markdown"], normal["json"], normal["mitre"], raw
166
+
167
+
168
+ def ui_quickscan(target):
169
+ raw = call_task("quickscan", {"target": target})
170
+ normal = format_result_for_ui(raw)
171
+ return normal["summary"], normal["markdown"], normal["json"], raw
172
+
173
+
174
+ # ---------------------------------------------------------------------
175
+ # MCP Bridge (Mode D)
176
+ # ---------------------------------------------------------------------
177
+
178
+ def ui_mcp_bridge(tool, args_json):
179
+ try:
180
+ payload = json.loads(args_json)
181
+ except Exception as exc:
182
+ err = {"error": f"Invalid JSON: {exc}"}
183
+ return json.dumps(err, indent=2), "", err
184
+
185
+ raw = call_task(tool, payload)
186
+ normal = format_result_for_ui(raw)
187
+ return normal["json"], normal["markdown"], raw
188
+
189
+
190
+ # ---------------------------------------------------------------------
191
+ # UI — Now with Analyst Copilot
192
+ # ---------------------------------------------------------------------
193
+
194
+ def build_interface() -> gr.Blocks:
195
+ with gr.Blocks(title="Parrot OSINT MCP Console") as demo:
196
+ gr.Markdown("# Parrot OSINT MCP Console")
197
+
198
+ # Store OSINT task results for injection into the Copilot
199
+ osint_result_state = gr.State([])
200
+
201
+ # ------------------------------------------
202
+ # MODE B — Dashboard
203
+ # ------------------------------------------
204
+ with gr.Tab("OSINT Dashboard"):
205
+ with gr.Tab("IP Lookup"):
206
+ ip = gr.Textbox(label="IP Address")
207
+ enrich = gr.Checkbox(value=True, label="Enrichment")
208
+ mitre = gr.Checkbox(value=True, label="MITRE mapping")
209
+ btn = gr.Button("Run")
210
+ summary = gr.Textbox(label="Summary")
211
+ md = gr.Markdown()
212
+ js = gr.Code(language="json")
213
+ mt = gr.Code(language="json")
214
+ st = gr.Code(language="json")
215
+
216
+ btn.click(
217
+ ui_lookup_ip,
218
+ inputs=[ip, enrich, mitre],
219
+ outputs=[summary, md, js, mt, st, osint_result_state],
220
+ )
221
+
222
+ # You already know: similar tabs for domain, hash, correlation, quickscan
223
+ # (keeping focus on Copilot integration)
224
+
225
+ # ------------------------------------------
226
+ # MODE D — MCP Bridge
227
+ # ------------------------------------------
228
+ with gr.Tab("MCP Bridge"):
229
+ tool = gr.Dropdown(sorted(TASK_REGISTRY.keys()))
230
+ args = gr.Code(label="Args JSON")
231
+ out_js = gr.Code(language="json")
232
+ out_md = gr.Markdown()
233
+
234
+ bridge_btn = gr.Button("Call Tool")
235
+ bridge_btn.click(
236
+ ui_mcp_bridge,
237
+ inputs=[tool, args],
238
+ outputs=[out_js, out_md, osint_result_state],
239
+ )
240
+
241
+ # ------------------------------------------
242
+ # MODE C — Analyst Copilot
243
+ # ------------------------------------------
244
+ with gr.Tab("Analyst Copilot"):
245
+ gr.Markdown("### Streaming TI Assistant with OSINT Context Injection")
246
+
247
+ system_msg = gr.Textbox(
248
+ label="System Prompt",
249
+ value=("You are a threat intelligence analyst. "
250
+ "You think slowly, explain clearly, identify TTPs, "
251
+ "and recommend next investigative steps."),
252
+ )
253
+
254
+ model = gr.Textbox(
255
+ label="HF Model (e.g., openai/gpt-oss-20b)",
256
+ value="openai/gpt-oss-20b",
257
+ )
258
+
259
+ chatbot = gr.ChatInterface(
260
+ respond,
261
+ additional_inputs=[
262
+ system_msg,
263
+ model,
264
+ gr.OAuthToken(label="HF Token"),
265
+ gr.Slider(0.1, 2.0, value=0.7, step=0.1, label="Temperature"),
266
+ gr.Slider(0.1, 1.0, value=0.95, step=0.05, label="Top-p"),
267
+ gr.Slider(1, 2048, value=512, step=1, label="Max Tokens"),
268
+ ],
269
+ type="messages",
270
+ )
271
+
272
+ inject_btn = gr.Button("Inject Latest OSINT Result")
273
+ inject_btn.click(
274
+ inject_osint_context,
275
+ inputs=[chatbot._chatbot_state, osint_result_state],
276
+ outputs=[chatbot._chatbot_state],
277
+ )
278
+
279
+ return demo
280
+
281
+
282
+ if __name__ == "__main__":
283
+ demo = build_interface()
284
+ demo.launch()