File size: 6,085 Bytes
575d372
 
 
8eac7f1
575d372
 
 
 
8eac7f1
 
575d372
 
 
 
 
 
 
8eac7f1
575d372
 
 
 
8eac7f1
575d372
 
 
 
 
 
8eac7f1
 
 
 
 
 
 
 
575d372
 
 
 
 
 
 
 
 
 
8eac7f1
 
 
 
 
 
 
575d372
 
 
 
 
 
 
8eac7f1
575d372
 
 
8eac7f1
575d372
 
 
 
 
 
 
 
 
 
8eac7f1
 
 
 
 
575d372
 
 
8eac7f1
575d372
8eac7f1
575d372
 
 
 
 
 
 
 
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
def generate_flow_html(active_phase="idle"):
    """
    Generates animated SVG for the MVM² Architecture Flow.
    Phases: 'idle', 'enhance', 'ocr', 'reasoning', 'heuristics', 'verification', 'consensus', 'success'
    """
    
    # Define colors
    bg_color = "#1e293b"
    accent = "#e63946" # Red to match local dashboard theme
    success = "#16a34a"
    text = "#94a3b8"
    
    # Pulse animation logic
    def get_pulse(phase):
        return 'active-pulse' if active_phase == phase else ''

    def get_node_style(phase):
        if active_phase == 'success': return f'stroke: {success}; filter: drop-shadow(0 0 8px {success});'
        if active_phase == phase: return f'stroke: {accent}; filter: drop-shadow(0 0 8px {accent});'
        return 'stroke: rgba(255,255,255,0.1);'

    html = f"""
    <div style="width: 100%; height: 400px; display: flex; justify-content: center; align-items: center; overflow: hidden; position: relative; background: rgba(30, 30, 30, 0.6); border-radius: 12px; border: 1px solid rgba(255,255,255,0.05);">
        <svg width="800" height="350" viewBox="0 0 800 350" preserveAspectRatio="xMidYMid meet">
            <!-- Definitions for markers and gradients -->
            <defs>
                <marker id="arrowhead" markerWidth="10" markerHeight="7" refX="0" refY="3.5" orient="auto">
                    <polygon points="0 0, 10 3.5, 0 7" fill="{text}" />
                </marker>
                <style>
                    .flow-line {{ stroke-dasharray: 1000; stroke-dashoffset: 1000; }}
                    .active-pulse {{ stroke-dashoffset: 0; animation: pulse-flow 2s infinite linear; stroke: {accent} !important; opacity: 1; }}
                    @keyframes pulse-flow {{ 0% {{ stroke-dashoffset: 1000; opacity: 0.3; }} 50% {{ opacity: 1; }} 100% {{ stroke-dashoffset: 0; opacity: 0.3; }} }}
                    .thinking circle {{ animation: thinking-pulse 1.5s infinite ease-in-out; }}
                    @keyframes thinking-pulse {{ 0%, 100% {{ transform: scale(1); opacity: 0.8; }} 50% {{ transform: scale(1.1); opacity: 1; filter: brightness(1.2); }} }}
                    .thinking {{ transform-origin: 450px 175px; }}
                </style>
            </defs>

            <!-- CONNECTIONS -->
            <!-- Enhance to OCR -->
            <path d="M100 175 H200" class="flow-line {get_pulse('enhance')}" stroke="{text}" stroke-width="2" marker-end="url(#arrowhead)" />
            
            <!-- OCR to Reasoning -->
            <path d="M300 175 H400" class="flow-line {get_pulse('ocr')}" stroke="{text}" stroke-width="2" marker-end="url(#arrowhead)" />
            
            <!-- Reasoning to Consensus (4 Parallel) -->
            <path d="M500 100 Q 525 100 550 175" class="flow-line {get_pulse('reasoning')}" stroke="{text}" stroke-width="1.5" />
            <path d="M500 150 Q 525 150 550 175" class="flow-line {get_pulse('reasoning')}" stroke="{text}" stroke-width="1.5" />
            <path d="M500 200 Q 525 200 550 175" class="flow-line {get_pulse('reasoning')}" stroke="{text}" stroke-width="1.5" />
            <path d="M500 250 Q 525 250 550 175" class="flow-line {get_pulse('reasoning')}" stroke="{text}" stroke-width="1.5" />

            <!-- Heuristics to Consensus -->
            <path d="M600 175 H640" class="flow-line {get_pulse('heuristics')}" stroke="{accent}" stroke-width="2" marker-end="url(#arrowhead)" />

            <!-- Symbolic Bridge -->
            <path d="M450 300 Q 450 250 450 250" class="flow-line {get_pulse('verification')}" stroke="{success}" stroke-width="3" stroke-dasharray="5,5" />

            <!-- NODES -->
            <!-- 1. Input/Enhance -->
            <rect x="20" y="140" width="80" height="70" rx="10" fill="{bg_color}" style="{get_node_style('enhance')}" />
            <text x="60" y="180" text-anchor="middle" fill="white" font-size="10" font-weight="600">ENHANCE</text>
            
            <!-- 2. OCR Module -->
            <circle cx="250" cy="175" r="45" fill="{bg_color}" style="{get_node_style('ocr')}" />
            <text x="250" y="180" text-anchor="middle" fill="white" font-size="10" font-weight="600">OCR</text>

            <!-- 3. Reasoning Agents (Parallel) -->
            <g class="{'thinking' if active_phase == 'reasoning' else ''}">
                <circle cx="450" cy="80" r="25" fill="{bg_color}" style="{get_node_style('reasoning')}" />
                <circle cx="450" cy="140" r="25" fill="{bg_color}" style="{get_node_style('reasoning')}" />
                <circle cx="450" cy="200" r="25" fill="{bg_color}" style="{get_node_style('reasoning')}" />
                <circle cx="450" cy="260" r="25" fill="{bg_color}" style="{get_node_style('reasoning')}" />
                <text x="450" y="45" text-anchor="middle" fill="{text}" font-size="10">REASONING</text>
            </g>

            <!-- 4. Heuristics Module -->
            <rect x="550" y="150" width="50" height="50" rx="5" fill="{bg_color}" style="{get_node_style('heuristics')}" />
            <text x="575" y="180" text-anchor="middle" fill="white" font-size="8" font-weight="600">FILTER</text>
            
            <!-- 5. Verification Bridge (SymPy) -->
            <rect x="400" y="300" width="100" height="40" rx="5" fill="{bg_color}" style="{get_node_style('verification')}" />
            <text x="450" y="325" text-anchor="middle" fill="{success}" font-size="10" font-weight="bold">SYMPY CORE</text>

            <!-- 6. Consensus -->
            <polygon points="650,125 750,175 650,225" fill="{bg_color}" style="{get_node_style('consensus')}" />
            <text x="680" y="180" text-anchor="middle" fill="white" font-size="10" font-weight="600">CONSENSUS</text>
        </svg>
        
        <div style="position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); font-size: 0.8em; color: {text};">
            Current Stage: <span style="color: {accent if active_phase != 'success' else success}; font-weight: bold; text-transform: uppercase;">{active_phase}</span>
        </div>
    </div>
    """
    return html