#!/usr/bin/env python3 import os import re import glob import json import base64 import zipfile import random import requests import openai from PIL import Image from urllib.parse import quote import streamlit as st import streamlit.components.v1 as components # Example base snippet: your normal Mermaid code DEFAULT_MERMAID = r""" flowchart LR U((User 😎)) -- "Talk 🗣️" --> LLM[LLM Agent 🤖\nExtract Info] click U "/?q=User%20😎" "Open 'User 😎'" "_blank" click LLM "/?q=LLM%20Agent%20Extract%20Info" "Open LLM Agent" "_blank" LLM -- "Query 🔍" --> HS[Hybrid Search 🔎\nVector+NER+Lexical] click HS "/?q=Hybrid%20Search%20Vector+NER+Lexical" "Open Hybrid Search" "_blank" HS -- "Reason 🤔" --> RE[Reasoning Engine 🛠️\nNeuralNetwork+Medical] click RE "/?q=Reasoning%20Engine%20NeuralNetwork+Medical" "Open Reasoning" "_blank" RE -- "Link 📡" --> KG((Knowledge Graph 📚\nOntology+GAR+RAG)) click KG "/?q=Knowledge%20Graph%20Ontology+GAR+RAG" "Open Knowledge Graph" "_blank" """ def parse_mermaid_edges(mermaid_text: str): """ 🍿 parse_mermaid_edges: - Find lines like `A -- "Label" --> B`. - Return adjacency dict: edges[A] = [(label, B), ...]. """ adjacency = {} # Regex to match lines like: A -- "Label" --> B edge_pattern = re.compile(r'(\S+)\s*--\s*"([^"]*)"\s*-->\s*(\S+)') # We split the text into lines and search for edges for line in mermaid_text.split('\n'): match = edge_pattern.search(line.strip()) if match: nodeA, label, nodeB = match.groups() if nodeA not in adjacency: adjacency[nodeA] = [] adjacency[nodeA].append((label, nodeB)) return adjacency def build_subgraph(adjacency, start_node): """ 🍎 build_subgraph: - BFS or DFS from start_node to gather edges. - For simplicity, we only gather direct edges from this node. - If you want a multi-level downstream search, do a BFS/DFS deeper. """ sub_edges = [] # If start_node has no adjacency, return empty if start_node not in adjacency: return sub_edges # For each edge out of start_node, store it in sub_edges for label, child in adjacency[start_node]: sub_edges.append((start_node, label, child)) return sub_edges def create_subgraph_mermaid(sub_edges, start_node): """ 🍄 create_subgraph_mermaid: - Given a list of edges in form (A, label, B), - Return a smaller flowchart snippet that includes them. """ # Start with the flowchart directive sub_mermaid = "flowchart LR\n" sub_mermaid += f" %% Subgraph for {start_node}\n" # For each edge, build a line: NodeA -- "Label" --> NodeB for (A, label, B) in sub_edges: # Potentially you can keep the original styles or shapes (like U((User 😎))). # If your original code has shapes, you can store them in a dict so A-> "U((User 😎))" etc. sub_mermaid += f' {A} -- "{label}" --> {B}\n' # Optionally add a comment to show the subgraph ends sub_mermaid += f" %% End of subgraph for {start_node}\n" return sub_mermaid def generate_mermaid_html(mermaid_code: str) -> str: """Tiny function to embed Mermaid code in HTML with a CDN.""" return f"""