chore: udate docs, add architecture diagrams
Some checks failed
Documentation Lint & Validation / Markdown Linting (push) Has been cancelled
Documentation Lint & Validation / Validate mdBook Configuration (push) Has been cancelled
Documentation Lint & Validation / Content & Structure Validation (push) Has been cancelled
mdBook Build & Deploy / Build mdBook (push) Has been cancelled
Rust CI / Security Audit (push) Has been cancelled
Rust CI / Check + Test + Lint (nightly) (push) Has been cancelled
Rust CI / Check + Test + Lint (stable) (push) Has been cancelled
Documentation Lint & Validation / Lint & Validation Summary (push) Has been cancelled
mdBook Build & Deploy / Documentation Quality Check (push) Has been cancelled
mdBook Build & Deploy / Deploy to GitHub Pages (push) Has been cancelled
mdBook Build & Deploy / Notification (push) Has been cancelled
576
assets/vapora_architecture.svg
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 1020" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700;800&family=Inter:wght@400;500;600&display=swap');
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Brand gradients -->
|
||||||
|
<linearGradient id="grad-main" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee"/>
|
||||||
|
<stop offset="50%" stop-color="#a855f7"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-cyan-purple" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee"/>
|
||||||
|
<stop offset="100%" stop-color="#a855f7"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-purple-pink" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#a855f7"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-vertical" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.8"/>
|
||||||
|
<stop offset="50%" stop-color="#a855f7" stop-opacity="0.5"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899" stop-opacity="0.3"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-cyan" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.15"/>
|
||||||
|
<stop offset="100%" stop-color="#22d3ee" stop-opacity="0.05"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-purple" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#a855f7" stop-opacity="0.15"/>
|
||||||
|
<stop offset="100%" stop-color="#a855f7" stop-opacity="0.05"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-pink" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#ec4899" stop-opacity="0.15"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899" stop-opacity="0.05"/>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Glow filters -->
|
||||||
|
<filter id="glow-sm">
|
||||||
|
<feGaussianBlur stdDeviation="2" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glow-md">
|
||||||
|
<feGaussianBlur stdDeviation="4" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glow-lg">
|
||||||
|
<feGaussianBlur stdDeviation="6" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glass-card">
|
||||||
|
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"/>
|
||||||
|
<feOffset dx="0" dy="1" result="shadow"/>
|
||||||
|
<feFlood flood-color="#000" flood-opacity="0.3" result="color"/>
|
||||||
|
<feComposite in="color" in2="shadow" operator="in" result="shadow"/>
|
||||||
|
<feMerge><feMergeNode in="shadow"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Animated particle marker -->
|
||||||
|
<circle id="particle-cyan" r="3" fill="#22d3ee" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-purple" r="3" fill="#a855f7" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-pink" r="3" fill="#ec4899" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-sm-cyan" r="2" fill="#22d3ee" filter="url(#glow-sm)"/>
|
||||||
|
<circle id="particle-sm-purple" r="2" fill="#a855f7" filter="url(#glow-sm)"/>
|
||||||
|
<circle id="particle-sm-pink" r="2" fill="#ec4899" filter="url(#glow-sm)"/>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- BACKGROUND -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<rect width="1400" height="1020" fill="#0a0a0a"/>
|
||||||
|
|
||||||
|
<!-- Subtle tech grid -->
|
||||||
|
<g opacity="0.04" stroke="#22d3ee" stroke-width="0.5">
|
||||||
|
<line x1="0" y1="0" x2="1400" y2="0"><animate attributeName="y1" values="0;1020" dur="60s" repeatCount="indefinite"/><animate attributeName="y2" values="0;1020" dur="60s" repeatCount="indefinite"/></line>
|
||||||
|
<line x1="100" y1="0" x2="100" y2="1020"/>
|
||||||
|
<line x1="250" y1="0" x2="250" y2="1020"/>
|
||||||
|
<line x1="400" y1="0" x2="400" y2="1020"/>
|
||||||
|
<line x1="550" y1="0" x2="550" y2="1020"/>
|
||||||
|
<line x1="700" y1="0" x2="700" y2="1020"/>
|
||||||
|
<line x1="850" y1="0" x2="850" y2="1020"/>
|
||||||
|
<line x1="1000" y1="0" x2="1000" y2="1020"/>
|
||||||
|
<line x1="1150" y1="0" x2="1150" y2="1020"/>
|
||||||
|
<line x1="1300" y1="0" x2="1300" y2="1020"/>
|
||||||
|
<line x1="0" y1="130" x2="1400" y2="130"/>
|
||||||
|
<line x1="0" y1="260" x2="1400" y2="260"/>
|
||||||
|
<line x1="0" y1="420" x2="1400" y2="420"/>
|
||||||
|
<line x1="0" y1="580" x2="1400" y2="580"/>
|
||||||
|
<line x1="0" y1="720" x2="1400" y2="720"/>
|
||||||
|
<line x1="0" y1="860" x2="1400" y2="860"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Ambient glow orbs -->
|
||||||
|
<circle cx="240" cy="350" r="180" fill="#22d3ee" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="160;200;160" dur="8s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="690" cy="360" r="175" fill="#a855f7" opacity="0.05">
|
||||||
|
<animate attributeName="r" values="175;195;175" dur="10s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="1130" cy="350" r="200" fill="#ec4899" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="180;220;180" dur="9s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- TITLE -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<text x="700" y="42" font-family="'JetBrains Mono', monospace" font-size="22" font-weight="800" fill="url(#grad-main)" letter-spacing="6" text-anchor="middle" filter="url(#glow-sm)">VAPORA ARCHITECTURE</text>
|
||||||
|
<text x="700" y="62" font-family="'Inter', sans-serif" font-size="11" fill="#a855f7" opacity="0.6" letter-spacing="3" text-anchor="middle">18 CRATES · 354 TESTS · 100% RUST</text>
|
||||||
|
|
||||||
|
<!-- Layer labels (left side) -->
|
||||||
|
<text x="30" y="115" font-family="'JetBrains Mono', monospace" font-size="10" fill="#22d3ee" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 115)">PRESENTATION</text>
|
||||||
|
<text x="30" y="290" font-family="'JetBrains Mono', monospace" font-size="10" fill="#a855f7" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 290)">SERVICES</text>
|
||||||
|
<text x="30" y="485" font-family="'JetBrains Mono', monospace" font-size="10" fill="#ec4899" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 485)">INTELLIGENCE</text>
|
||||||
|
<text x="30" y="640" font-family="'JetBrains Mono', monospace" font-size="10" fill="#22d3ee" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 640)">DATA</text>
|
||||||
|
<text x="30" y="850" font-family="'JetBrains Mono', monospace" font-size="10" fill="#a855f7" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 850)">PROVIDERS</text>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 1: FRONTEND (y=80) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Frontend card -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="490" y="80" width="420" height="65" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.4" stroke-width="2"/>
|
||||||
|
<rect x="494" y="80" width="412" height="1.5" rx="1" fill="url(#grad-main)" opacity="0.8"/>
|
||||||
|
<text x="700" y="106" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#22d3ee" text-anchor="middle" filter="url(#glow-sm)">Leptos WASM Frontend</text>
|
||||||
|
<text x="700" y="124" font-family="'Inter', sans-serif" font-size="10" fill="#ffffff" opacity="0.5" text-anchor="middle">Kanban Board · Glassmorphism UI · UnoCSS · Reactive Components</text>
|
||||||
|
<!-- Pulse ring -->
|
||||||
|
<rect x="490" y="80" width="420" height="65" rx="8" fill="none" stroke="#22d3ee" stroke-opacity="0.15">
|
||||||
|
<animate attributeName="stroke-opacity" values="0.15;0.3;0.15" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTION: Frontend → Services -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Frontend to Backend -->
|
||||||
|
<path id="path-fe-be" d="M 580 145 L 580 160 Q 580 175 480 175 L 280 175 Q 260 175 260 195 L 260 210" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.8"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-fe-be"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- Frontend to Agents -->
|
||||||
|
<line x1="700" y1="145" x2="700" y2="210" stroke="#a855f7" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.8"><animateMotion dur="2s" repeatCount="indefinite" path="M 700 145 L 700 210"/></use>
|
||||||
|
|
||||||
|
<!-- Frontend to MCP -->
|
||||||
|
<path id="path-fe-mcp" d="M 820 145 L 820 160 Q 820 175 920 175 L 1100 175 Q 1140 175 1140 195 L 1140 210" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.8"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-fe-mcp"/></animateMotion></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 2: SERVICES (y=210) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Backend / Axum API -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="100" y="210" width="310" height="100" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="104" y="210" width="302" height="1.5" rx="1" fill="#22d3ee" opacity="0.6"/>
|
||||||
|
<text x="255" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#22d3ee" text-anchor="middle">Axum Backend API</text>
|
||||||
|
<text x="255" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">40+ REST Endpoints · 161 Tests</text>
|
||||||
|
<!-- Sub-items -->
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.35">
|
||||||
|
<text x="120" y="278">Projects</text>
|
||||||
|
<text x="180" y="278">Tasks</text>
|
||||||
|
<text x="225" y="278">Agents</text>
|
||||||
|
<text x="280" y="278">Workflows</text>
|
||||||
|
<text x="350" y="278">Proposals</text>
|
||||||
|
<text x="120" y="294">Swarm</text>
|
||||||
|
<text x="175" y="294">Metrics</text>
|
||||||
|
<text x="235" y="294">RLM API</text>
|
||||||
|
<text x="300" y="294">WebSocket</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Agent Runtime -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="540" y="210" width="310" height="100" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="544" y="210" width="302" height="1.5" rx="1" fill="#a855f7" opacity="0.6"/>
|
||||||
|
<text x="695" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#a855f7" text-anchor="middle">Agent Runtime</text>
|
||||||
|
<text x="695" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Orchestration · Learning Profiles · 71 Tests</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.35">
|
||||||
|
<text x="560" y="278">Registry</text>
|
||||||
|
<text x="625" y="278">Coordinator</text>
|
||||||
|
<text x="720" y="278">Scoring</text>
|
||||||
|
<text x="785" y="278">Profiles</text>
|
||||||
|
<text x="560" y="294">12 Roles</text>
|
||||||
|
<text x="630" y="294">Health Checks</text>
|
||||||
|
<text x="735" y="294">Recency Bias</text>
|
||||||
|
</g>
|
||||||
|
<!-- Heartbeat animation -->
|
||||||
|
<circle cx="835" cy="225" r="4" fill="#a855f7" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="3;5;3" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.3;0.6;0.3" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- MCP Gateway -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="980" y="210" width="310" height="100" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="984" y="210" width="302" height="1.5" rx="1" fill="#ec4899" opacity="0.6"/>
|
||||||
|
<text x="1135" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#ec4899" text-anchor="middle">MCP Gateway</text>
|
||||||
|
<text x="1135" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Model Context Protocol · Plugin System</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.35">
|
||||||
|
<text x="1000" y="278">Stdio Transport</text>
|
||||||
|
<text x="1105" y="278">SSE Transport</text>
|
||||||
|
<text x="1210" y="278">JSON-RPC</text>
|
||||||
|
<text x="1000" y="294">6 Tools</text>
|
||||||
|
<text x="1060" y="294">Tool Registry</text>
|
||||||
|
<text x="1160" y="294">Schema Validation</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- A2A Protocol (small card overlapping) -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="445" y="280" width="86" height="35" rx="6" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="488" y="300" font-family="'JetBrains Mono', monospace" font-size="9" font-weight="700" fill="#a855f7" opacity="0.6" text-anchor="middle">A2A Protocol</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Services → Intelligence -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Backend → RLM -->
|
||||||
|
<path id="path-be-rlm" d="M 200 310 L 200 380" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 200 310 L 200 380"/></use>
|
||||||
|
|
||||||
|
<!-- Backend → SurrealDB (arco por la derecha para evitar KG) -->
|
||||||
|
<path id="path-be-sdb" d="M 320 310 L 320 340 Q 320 360 360 360 L 420 360 Q 435 360 435 380 Q 435 580 420 580 L 420 585" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.35" stroke-dasharray="4 4"/>
|
||||||
|
|
||||||
|
<!-- Agents → LLM Router -->
|
||||||
|
<line x1="695" y1="310" x2="695" y2="380" stroke="#a855f7" stroke-width="2.4" stroke-opacity="0.3"/>
|
||||||
|
<use href="#particle-purple" opacity="0.8"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 695 310 L 695 380"/></use>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.5"><animateMotion dur="1.5s" begin="0.75s" repeatCount="indefinite" path="M 695 310 L 695 380"/></use>
|
||||||
|
|
||||||
|
<!-- Agents → Swarm -->
|
||||||
|
<path id="path-ag-sw" d="M 800 310 L 800 340 Q 800 355 900 355 L 1050 355 Q 1070 355 1070 375 L 1070 380" fill="none" stroke="#a855f7" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.6"><animateMotion dur="2.2s" repeatCount="indefinite"><mpath href="#path-ag-sw"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- MCP → Agents -->
|
||||||
|
<path id="path-mcp-ag" d="M 1020 310 L 1020 320 Q 1020 332 920 332 L 810 332 Q 800 332 800 320 L 800 310" fill="none" stroke="#ec4899" stroke-width="1.6" stroke-opacity="0.35" stroke-dasharray="3 3"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 3: INTELLIGENCE (y=380) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- RLM Engine -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="60" y="380" width="340" height="130" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="64" y="380" width="332" height="2" rx="1" fill="url(#grad-main)" opacity="0.7"/>
|
||||||
|
<text x="230" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="url(#grad-main)" text-anchor="middle" filter="url(#glow-sm)">RLM Engine</text>
|
||||||
|
<text x="230" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Recursive Language Models · 38 Tests · 17k+ LOC</text>
|
||||||
|
|
||||||
|
<!-- RLM sub-components as mini pills -->
|
||||||
|
<g transform="translate(75, 435)">
|
||||||
|
<!-- Chunking -->
|
||||||
|
<rect x="0" y="0" width="80" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="40" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Chunking</text>
|
||||||
|
<!-- Hybrid Search -->
|
||||||
|
<rect x="90" y="0" width="95" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="137" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Hybrid Search</text>
|
||||||
|
<!-- Dispatcher -->
|
||||||
|
<rect x="195" y="0" width="80" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="235" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Dispatcher</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(75, 465)">
|
||||||
|
<!-- BM25 -->
|
||||||
|
<rect x="0" y="0" width="65" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="32" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">BM25</text>
|
||||||
|
<!-- Semantic -->
|
||||||
|
<rect x="75" y="0" width="70" height="20" rx="3" fill="rgba(168,85,247,0.08)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="110" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Semantic</text>
|
||||||
|
<!-- RRF -->
|
||||||
|
<rect x="155" y="0" width="50" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="180" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">RRF</text>
|
||||||
|
<!-- Sandbox -->
|
||||||
|
<rect x="215" y="0" width="60" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="245" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Sandbox</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Animated search indicator -->
|
||||||
|
<g transform="translate(370, 400)">
|
||||||
|
<circle r="6" fill="none" stroke="#22d3ee" stroke-width="0.8" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="4;8;4" dur="3s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.4;0.1;0.4" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle r="3" fill="#22d3ee" opacity="0.07">
|
||||||
|
<animate attributeName="opacity" values="0.2;0.5;0.2" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- LLM Router -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="500" y="380" width="380" height="130" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="504" y="380" width="372" height="2" rx="1" fill="#a855f7" opacity="0.7"/>
|
||||||
|
<text x="690" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#a855f7" text-anchor="middle" filter="url(#glow-sm)">Multi-IA LLM Router</text>
|
||||||
|
<text x="690" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Budget Enforcement · Cost Tracking · 53 Tests</text>
|
||||||
|
|
||||||
|
<!-- Router sub-components -->
|
||||||
|
<g transform="translate(515, 435)">
|
||||||
|
<rect x="0" y="0" width="95" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="47" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Rule Router</text>
|
||||||
|
<rect x="105" y="0" width="115" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="162" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Budget Manager</text>
|
||||||
|
<rect x="230" y="0" width="110" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="285" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Cost Tracker</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(515, 465)">
|
||||||
|
<rect x="0" y="0" width="95" height="20" rx="3" fill="rgba(168,85,247,0.08)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="47" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Fallback Chain</text>
|
||||||
|
<rect x="105" y="0" width="90" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="150" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Cost Ranker</text>
|
||||||
|
<rect x="205" y="0" width="80" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="245" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Providers</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Routing indicator animation -->
|
||||||
|
<g transform="translate(855, 400)">
|
||||||
|
<line x1="-6" y1="0" x2="6" y2="0" stroke="#a855f7" stroke-width="1.5" opacity="0.5">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="4s" repeatCount="indefinite"/>
|
||||||
|
</line>
|
||||||
|
<line x1="0" y1="-6" x2="0" y2="6" stroke="#ec4899" stroke-width="1.5" opacity="0.5">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="4s" repeatCount="indefinite"/>
|
||||||
|
</line>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Swarm Coordinator -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="980" y="380" width="310" height="130" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="984" y="380" width="302" height="1.5" rx="1" fill="#ec4899" opacity="0.6"/>
|
||||||
|
<text x="1135" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#ec4899" text-anchor="middle" filter="url(#glow-sm)">Swarm Coordinator</text>
|
||||||
|
<text x="1135" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Load Balancing · Prometheus · 6 Tests</text>
|
||||||
|
|
||||||
|
<g transform="translate(995, 435)">
|
||||||
|
<rect x="0" y="0" width="90" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="45" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Assignment</text>
|
||||||
|
<rect x="100" y="0" width="90" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="145" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Filtering</text>
|
||||||
|
<rect x="200" y="0" width="80" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="240" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Metrics</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(995, 465)">
|
||||||
|
<rect x="0" y="0" width="130" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="65" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">success_rate / (1+load)</text>
|
||||||
|
<rect x="140" y="0" width="80" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="180" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Capabilities</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Swarm pulse -->
|
||||||
|
<circle cx="1270" cy="395" r="3" fill="#ec4899" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="2;5;2" dur="2s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.2;0.5;0.2" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- RLM → LLM Router connection -->
|
||||||
|
<path id="path-rlm-llm" d="M 400 445 L 500 445" fill="none" stroke="url(#grad-cyan-purple)" stroke-width="3" stroke-opacity="0.3"/>
|
||||||
|
<use href="#particle-cyan" opacity="0.7"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 400 445 L 500 445"/></use>
|
||||||
|
|
||||||
|
<!-- LLM Router → Swarm connection -->
|
||||||
|
<path d="M 880 445 L 980 445" fill="none" stroke="url(#grad-purple-pink)" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.6"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 880 445 L 980 445"/></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Intelligence → Data -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- RLM → KG -->
|
||||||
|
<path id="path-rlm-kg" d="M 160 510 L 160 575" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 160 510 L 160 575"/></use>
|
||||||
|
|
||||||
|
<!-- RLM → SurrealDB -->
|
||||||
|
<path id="path-rlm-sdb" d="M 300 510 L 300 540 Q 300 555 400 555 L 530 555 Q 545 555 545 575" fill="none" stroke="#22d3ee" stroke-width="2.4" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-cyan" opacity="0.7"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-rlm-sdb"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- LLM Router → Providers (goes down below data) -->
|
||||||
|
<path id="path-llm-providers" d="M 790 510 L 790 725" fill="none" stroke="#a855f7" stroke-width="3" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-purple" opacity="0.8"><animateMotion dur="3s" repeatCount="indefinite" path="M 790 510 L 790 725"/></use>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.5"><animateMotion dur="3s" begin="1.5s" repeatCount="indefinite" path="M 790 510 L 790 725"/></use>
|
||||||
|
|
||||||
|
<!-- Swarm → NATS -->
|
||||||
|
<path id="path-sw-nats" d="M 1135 510 L 1135 575" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 1135 510 L 1135 575"/></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 4: DATA LAYER (y=575) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Knowledge Graph -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="60" y="575" width="260" height="100" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="2"/>
|
||||||
|
<rect x="60" y="575" width="260" height="1.5" rx="1" fill="#22d3ee" opacity="0.5"/>
|
||||||
|
<text x="190" y="600" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Knowledge Graph</text>
|
||||||
|
<text x="190" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.4" text-anchor="middle">Temporal History · Learning Curves · 20 Tests</text>
|
||||||
|
<g transform="translate(75, 630)">
|
||||||
|
<rect x="0" y="0" width="80" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="40" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Executions</text>
|
||||||
|
<rect x="90" y="0" width="70" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="125" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Similarity</text>
|
||||||
|
<rect x="170" y="0" width="60" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="200" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Causal</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SurrealDB -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="420" y="575" width="340" height="100" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="420" y="575" width="340" height="2" rx="1" fill="url(#grad-main)" opacity="0.6"/>
|
||||||
|
<text x="590" y="600" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="url(#grad-main)" text-anchor="middle" filter="url(#glow-sm)">SurrealDB</text>
|
||||||
|
<text x="590" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Multi-Model Database · Multi-Tenant Scopes</text>
|
||||||
|
|
||||||
|
<g transform="translate(435, 630)">
|
||||||
|
<rect x="0" y="0" width="65" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="32" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Projects</text>
|
||||||
|
<rect x="75" y="0" width="50" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="100" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Tasks</text>
|
||||||
|
<rect x="135" y="0" width="55" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="162" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Agents</text>
|
||||||
|
<rect x="200" y="0" width="55" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="227" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Chunks</text>
|
||||||
|
<rect x="265" y="0" width="45" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="287" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">A2A</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- DB activity indicator -->
|
||||||
|
<g transform="translate(735, 590)">
|
||||||
|
<rect x="0" y="0" width="2" height="10" fill="#22d3ee" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="6;12;6" dur="1.2s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="5" y="0" width="2" height="8" fill="#a855f7" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="8;14;8" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="10" y="0" width="2" height="12" fill="#ec4899" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="10;16;10" dur="1s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- KG → SurrealDB -->
|
||||||
|
<line x1="320" y1="630" x2="420" y2="630" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 320 630 L 420 630"/></use>
|
||||||
|
|
||||||
|
<!-- NATS JetStream -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="860" y="575" width="340" height="100" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="860" y="575" width="340" height="1.5" rx="1" fill="#ec4899" opacity="0.5"/>
|
||||||
|
<text x="1030" y="600" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#ec4899" text-anchor="middle" filter="url(#glow-sm)">NATS JetStream</text>
|
||||||
|
<text x="1030" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Message Queue · Async Coordination · Pub/Sub</text>
|
||||||
|
|
||||||
|
<g transform="translate(875, 630)">
|
||||||
|
<rect x="0" y="0" width="75" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="37" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Agent Jobs</text>
|
||||||
|
<rect x="85" y="0" width="75" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="122" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Workflows</text>
|
||||||
|
<rect x="170" y="0" width="70" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="205" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Proposals</text>
|
||||||
|
<rect x="250" y="0" width="60" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="280" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">A2A</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Message pulse animation -->
|
||||||
|
<g transform="translate(1125, 590)">
|
||||||
|
<circle r="4" fill="none" stroke="#ffffff" stroke-width="2" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="3;8;3" dur="2s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="1;0.5;1" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle r="3" fill="#ffffff" opacity="0.07">
|
||||||
|
<animate attributeName="opacity" values="0.8;1;0.8" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SurrealDB ↔ NATS bridge line -->
|
||||||
|
<line x1="760" y1="625" x2="860" y2="625" stroke="url(#grad-purple-pink)" stroke-width="0.8" stroke-opacity="0.4" stroke-dasharray="4 3"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Data → Providers -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Central provider trunk (from LLM Router, already drawn) -->
|
||||||
|
<!-- Branch to each provider -->
|
||||||
|
<path id="path-to-claude" d="M 790 725 Q 790 750 500 750 L 245 750 Q 225 750 225 785" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-to-claude"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-openai" d="M 790 725 Q 790 760 600 760 L 555 760 Q 545 760 545 785" fill="none" stroke="#a855f7" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.6"><animateMotion dur="2s" repeatCount="indefinite"><mpath href="#path-to-openai"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-gemini" d="M 790 725 Q 790 770 810 770 L 855 770 Q 865 770 865 785" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.6"><animateMotion dur="2.2s" repeatCount="indefinite"><mpath href="#path-to-gemini"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-ollama" d="M 790 725 Q 790 750 900 750 L 1155 750 Q 1175 750 1175 785" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="2.8s" repeatCount="indefinite"><mpath href="#path-to-ollama"/></animateMotion></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 5: LLM PROVIDERS (y=810) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Claude -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="100" y="785" width="250" height="55" rx="6" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="225" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Anthropic Claude</text>
|
||||||
|
<text x="225" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.4" text-anchor="middle">Opus · Sonnet · Haiku</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- OpenAI -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="420" y="785" width="250" height="55" rx="6" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="545" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#a855f7" text-anchor="middle">OpenAI</text>
|
||||||
|
<text x="545" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.4" text-anchor="middle">GPT-4 · GPT-4o · GPT-3.5</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Gemini -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="740" y="785" width="250" height="55" rx="6" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="865" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#ec4899" text-anchor="middle">Google Gemini</text>
|
||||||
|
<text x="865" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.4" text-anchor="middle">2.0 Pro · Flash · 1.5 Pro</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Ollama -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="1060" y="785" width="250" height="55" rx="6" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="1185" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Ollama (Local)</text>
|
||||||
|
<text x="1185" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.4" text-anchor="middle">Llama · Mistral · CodeLlama</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- SUPPORTING CRATES (bottom strip) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<g transform="translate(0, 882)">
|
||||||
|
<rect x="60" y="0" width="1280" height="50" rx="6" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="700" y="16" font-family="'JetBrains Mono', monospace" font-size="9" fill="#a855f7" opacity="0.7" text-anchor="middle" letter-spacing="2">SUPPORTING CRATES</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="10" opacity="0.6" text-anchor="middle">
|
||||||
|
<text x="130" y="36" fill="#22d3ee">vapora-shared</text>
|
||||||
|
<text x="260" y="36" fill="#a855f7">vapora-tracking</text>
|
||||||
|
<text x="400" y="36" fill="#ec4899">vapora-telemetry</text>
|
||||||
|
<text x="540" y="36" fill="#22d3ee">vapora-analytics</text>
|
||||||
|
<text x="680" y="36" fill="#a855f7">vapora-worktree</text>
|
||||||
|
<text x="820" y="36" fill="#ec4899">vapora-doc-lifecycle</text>
|
||||||
|
<text x="975" y="36" fill="#22d3ee">vapora-workflow-engine</text>
|
||||||
|
<text x="1140" y="36" fill="#a855f7">vapora-cli</text>
|
||||||
|
<text x="1250" y="36" fill="#ec4899">vapora-leptos-ui</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- OBSERVABILITY STRIP (right edge) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<g transform="translate(1340, 80)">
|
||||||
|
<rect x="0" y="0" width="4" height="790" rx="2" fill="url(#grad-vertical)" opacity="0.3">
|
||||||
|
<animate attributeName="opacity" values="0.2;0.4;0.2" dur="5s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<text x="15" y="400" font-family="'JetBrains Mono', monospace" font-size="9" fill="#a855f7" opacity="0.6" letter-spacing="2" text-anchor="middle" transform="rotate(90 15 400)">PROMETHEUS · GRAFANA · OPENTELEMETRY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- FOOTER -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<text x="700" y="970" font-family="'JetBrains Mono', monospace" font-size="11" font-weight="700" fill="url(#grad-main)" text-anchor="middle" opacity="0.7" letter-spacing="3">VAPORA v1.2.0</text>
|
||||||
|
<text x="700" y="993" font-family="'Inter', sans-serif" font-size="9" fill="#a855f7" opacity="0.6" text-anchor="middle" letter-spacing="1">Evaporate complexity · Full-Stack Rust · Production Ready</text>
|
||||||
|
|
||||||
|
<!-- Bottom gradient bar -->
|
||||||
|
<rect x="400" y="1005" width="600" height="2" rx="1" fill="url(#grad-main)" opacity="0.3"/>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 42 KiB |
576
assets/vapora_architecture_white.svg
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 1020" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700;800&family=Inter:wght@400;500;600&display=swap');
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Brand gradients -->
|
||||||
|
<linearGradient id="grad-main" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee"/>
|
||||||
|
<stop offset="50%" stop-color="#a855f7"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-cyan-purple" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee"/>
|
||||||
|
<stop offset="100%" stop-color="#a855f7"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-purple-pink" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#a855f7"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-vertical" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.8"/>
|
||||||
|
<stop offset="50%" stop-color="#a855f7" stop-opacity="0.5"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899" stop-opacity="0.3"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-cyan" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.12"/>
|
||||||
|
<stop offset="100%" stop-color="#22d3ee" stop-opacity="0.03"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-purple" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#a855f7" stop-opacity="0.12"/>
|
||||||
|
<stop offset="100%" stop-color="#a855f7" stop-opacity="0.03"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-pink" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#ec4899" stop-opacity="0.12"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899" stop-opacity="0.03"/>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Glow filters -->
|
||||||
|
<filter id="glow-sm">
|
||||||
|
<feGaussianBlur stdDeviation="0.5" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glow-md">
|
||||||
|
<feGaussianBlur stdDeviation="4" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glow-lg">
|
||||||
|
<feGaussianBlur stdDeviation="6" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glass-card">
|
||||||
|
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"/>
|
||||||
|
<feOffset dx="0" dy="1" result="shadow"/>
|
||||||
|
<feFlood flood-color="#000" flood-opacity="0.3" result="color"/>
|
||||||
|
<feComposite in="color" in2="shadow" operator="in" result="shadow"/>
|
||||||
|
<feMerge><feMergeNode in="shadow"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Animated particle marker -->
|
||||||
|
<circle id="particle-cyan" r="3" fill="#22d3ee" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-purple" r="3" fill="#a855f7" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-pink" r="3" fill="#ec4899" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-sm-cyan" r="2" fill="#22d3ee" filter="url(#glow-sm)"/>
|
||||||
|
<circle id="particle-sm-purple" r="2" fill="#a855f7" filter="url(#glow-sm)"/>
|
||||||
|
<circle id="particle-sm-pink" r="2" fill="#ec4899" filter="url(#glow-sm)"/>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- BACKGROUND -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<rect width="1400" height="1020" fill="#ffffff"/>
|
||||||
|
|
||||||
|
<!-- Subtle tech grid -->
|
||||||
|
<g opacity="0.08" stroke="#22d3ee" stroke-width="0.5">
|
||||||
|
<line x1="0" y1="0" x2="1400" y2="0"><animate attributeName="y1" values="0;1020" dur="60s" repeatCount="indefinite"/><animate attributeName="y2" values="0;1020" dur="60s" repeatCount="indefinite"/></line>
|
||||||
|
<line x1="100" y1="0" x2="100" y2="1020"/>
|
||||||
|
<line x1="250" y1="0" x2="250" y2="1020"/>
|
||||||
|
<line x1="400" y1="0" x2="400" y2="1020"/>
|
||||||
|
<line x1="550" y1="0" x2="550" y2="1020"/>
|
||||||
|
<line x1="700" y1="0" x2="700" y2="1020"/>
|
||||||
|
<line x1="850" y1="0" x2="850" y2="1020"/>
|
||||||
|
<line x1="1000" y1="0" x2="1000" y2="1020"/>
|
||||||
|
<line x1="1150" y1="0" x2="1150" y2="1020"/>
|
||||||
|
<line x1="1300" y1="0" x2="1300" y2="1020"/>
|
||||||
|
<line x1="0" y1="130" x2="1400" y2="130"/>
|
||||||
|
<line x1="0" y1="260" x2="1400" y2="260"/>
|
||||||
|
<line x1="0" y1="420" x2="1400" y2="420"/>
|
||||||
|
<line x1="0" y1="580" x2="1400" y2="580"/>
|
||||||
|
<line x1="0" y1="720" x2="1400" y2="720"/>
|
||||||
|
<line x1="0" y1="860" x2="1400" y2="860"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Ambient glow orbs -->
|
||||||
|
<circle cx="240" cy="350" r="180" fill="#22d3ee" opacity="0.05">
|
||||||
|
<animate attributeName="r" values="160;200;160" dur="8s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="690" cy="360" r="175" fill="#a855f7" opacity="0.04">
|
||||||
|
<animate attributeName="r" values="175;195;175" dur="10s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="1130" cy="350" r="200" fill="#ec4899" opacity="0.05">
|
||||||
|
<animate attributeName="r" values="180;220;180" dur="9s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- TITLE -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<text x="700" y="42" font-family="'JetBrains Mono', monospace" font-size="22" font-weight="800" fill="url(#grad-main)" letter-spacing="6" text-anchor="middle" filter="url(#glow-sm)">VAPORA ARCHITECTURE</text>
|
||||||
|
<text x="700" y="62" font-family="'Inter', sans-serif" font-size="11" fill="#a855f7" opacity="0.6" letter-spacing="3" text-anchor="middle">18 CRATES · 354 TESTS · 100% RUST</text>
|
||||||
|
|
||||||
|
<!-- Layer labels (left side) -->
|
||||||
|
<text x="30" y="115" font-family="'JetBrains Mono', monospace" font-size="10" fill="#22d3ee" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 115)">PRESENTATION</text>
|
||||||
|
<text x="30" y="290" font-family="'JetBrains Mono', monospace" font-size="10" fill="#a855f7" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 290)">SERVICES</text>
|
||||||
|
<text x="30" y="485" font-family="'JetBrains Mono', monospace" font-size="10" fill="#ec4899" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 485)">INTELLIGENCE</text>
|
||||||
|
<text x="30" y="640" font-family="'JetBrains Mono', monospace" font-size="10" fill="#22d3ee" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 640)">DATA</text>
|
||||||
|
<text x="30" y="850" font-family="'JetBrains Mono', monospace" font-size="10" fill="#a855f7" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 850)">PROVIDERS</text>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 1: FRONTEND (y=80) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Frontend card -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="490" y="80" width="420" height="65" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.4" stroke-width="1"/>
|
||||||
|
<rect x="494" y="80" width="412" height="1.5" rx="1" fill="url(#grad-main)" opacity="0.8"/>
|
||||||
|
<text x="700" y="106" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#22d3ee" text-anchor="middle" filter="url(#glow-sm)">Leptos WASM Frontend</text>
|
||||||
|
<text x="700" y="124" font-family="'Inter', sans-serif" font-size="10" fill="#1f2937" opacity="0.85" text-anchor="middle">Kanban Board · Glassmorphism UI · UnoCSS · Reactive Components</text>
|
||||||
|
<!-- Pulse ring -->
|
||||||
|
<rect x="490" y="80" width="420" height="65" rx="8" fill="none" stroke="#22d3ee" stroke-opacity="0.15">
|
||||||
|
<animate attributeName="stroke-opacity" values="0.15;0.3;0.15" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTION: Frontend → Services -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Frontend to Backend -->
|
||||||
|
<path id="path-fe-be" d="M 580 145 L 580 160 Q 580 175 480 175 L 280 175 Q 260 175 260 195 L 260 210" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.8"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-fe-be"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- Frontend to Agents -->
|
||||||
|
<line x1="700" y1="145" x2="700" y2="210" stroke="#a855f7" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.8"><animateMotion dur="2s" repeatCount="indefinite" path="M 700 145 L 700 210"/></use>
|
||||||
|
|
||||||
|
<!-- Frontend to MCP -->
|
||||||
|
<path id="path-fe-mcp" d="M 820 145 L 820 160 Q 820 175 920 175 L 1100 175 Q 1140 175 1140 195 L 1140 210" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.8"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-fe-mcp"/></animateMotion></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 2: SERVICES (y=210) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Backend / Axum API -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="100" y="210" width="310" height="100" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="104" y="210" width="302" height="1.5" rx="1" fill="#22d3ee" opacity="0.6"/>
|
||||||
|
<text x="255" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#22d3ee" text-anchor="middle">Axum Backend API</text>
|
||||||
|
<text x="255" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">40+ REST Endpoints · 161 Tests</text>
|
||||||
|
<!-- Sub-items -->
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.65">
|
||||||
|
<text x="120" y="278">Projects</text>
|
||||||
|
<text x="180" y="278">Tasks</text>
|
||||||
|
<text x="225" y="278">Agents</text>
|
||||||
|
<text x="280" y="278">Workflows</text>
|
||||||
|
<text x="350" y="278">Proposals</text>
|
||||||
|
<text x="120" y="294">Swarm</text>
|
||||||
|
<text x="175" y="294">Metrics</text>
|
||||||
|
<text x="235" y="294">RLM API</text>
|
||||||
|
<text x="300" y="294">WebSocket</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Agent Runtime -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="540" y="210" width="310" height="100" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="544" y="210" width="302" height="1.5" rx="1" fill="#a855f7" opacity="0.6"/>
|
||||||
|
<text x="695" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#a855f7" text-anchor="middle">Agent Runtime</text>
|
||||||
|
<text x="695" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Orchestration · Learning Profiles · 71 Tests</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.65">
|
||||||
|
<text x="560" y="278">Registry</text>
|
||||||
|
<text x="625" y="278">Coordinator</text>
|
||||||
|
<text x="720" y="278">Scoring</text>
|
||||||
|
<text x="785" y="278">Profiles</text>
|
||||||
|
<text x="560" y="294">12 Roles</text>
|
||||||
|
<text x="630" y="294">Health Checks</text>
|
||||||
|
<text x="735" y="294">Recency Bias</text>
|
||||||
|
</g>
|
||||||
|
<!-- Heartbeat animation -->
|
||||||
|
<circle cx="835" cy="225" r="4" fill="#a855f7" opacity="0.04">
|
||||||
|
<animate attributeName="r" values="3;5;3" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.3;0.6;0.3" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- MCP Gateway -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="980" y="210" width="310" height="100" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="984" y="210" width="302" height="1.5" rx="1" fill="#ec4899" opacity="0.6"/>
|
||||||
|
<text x="1135" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#ec4899" text-anchor="middle">MCP Gateway</text>
|
||||||
|
<text x="1135" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Model Context Protocol · Plugin System</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.65">
|
||||||
|
<text x="1000" y="278">Stdio Transport</text>
|
||||||
|
<text x="1105" y="278">SSE Transport</text>
|
||||||
|
<text x="1210" y="278">JSON-RPC</text>
|
||||||
|
<text x="1000" y="294">6 Tools</text>
|
||||||
|
<text x="1060" y="294">Tool Registry</text>
|
||||||
|
<text x="1160" y="294">Schema Validation</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- A2A Protocol (small card overlapping) -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="445" y="280" width="86" height="35" rx="6" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="488" y="300" font-family="'JetBrains Mono', monospace" font-size="9" font-weight="700" fill="#a855f7" opacity="0.6" text-anchor="middle">A2A Protocol</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Services → Intelligence -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Backend → RLM -->
|
||||||
|
<path id="path-be-rlm" d="M 200 310 L 200 380" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 200 310 L 200 380"/></use>
|
||||||
|
|
||||||
|
<!-- Backend → SurrealDB (arco por la derecha para evitar KG) -->
|
||||||
|
<path id="path-be-sdb" d="M 320 310 L 320 340 Q 320 360 360 360 L 420 360 Q 435 360 435 380 Q 435 580 420 580 L 420 585" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.35" stroke-dasharray="4 4"/>
|
||||||
|
|
||||||
|
<!-- Agents → LLM Router -->
|
||||||
|
<line x1="695" y1="310" x2="695" y2="380" stroke="#a855f7" stroke-width="2.4" stroke-opacity="0.3"/>
|
||||||
|
<use href="#particle-purple" opacity="0.8"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 695 310 L 695 380"/></use>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.5"><animateMotion dur="1.5s" begin="0.75s" repeatCount="indefinite" path="M 695 310 L 695 380"/></use>
|
||||||
|
|
||||||
|
<!-- Agents → Swarm -->
|
||||||
|
<path id="path-ag-sw" d="M 800 310 L 800 340 Q 800 355 900 355 L 1050 355 Q 1070 355 1070 375 L 1070 380" fill="none" stroke="#a855f7" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.6"><animateMotion dur="2.2s" repeatCount="indefinite"><mpath href="#path-ag-sw"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- MCP → Agents -->
|
||||||
|
<path id="path-mcp-ag" d="M 1020 310 L 1020 320 Q 1020 332 920 332 L 810 332 Q 800 332 800 320 L 800 310" fill="none" stroke="#ec4899" stroke-width="1.6" stroke-opacity="0.35" stroke-dasharray="3 3"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 3: INTELLIGENCE (y=380) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- RLM Engine -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="60" y="380" width="340" height="130" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="64" y="380" width="332" height="2" rx="1" fill="url(#grad-main)" opacity="0.7"/>
|
||||||
|
<text x="230" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="url(#grad-main)" text-anchor="middle" filter="url(#glow-sm)">RLM Engine</text>
|
||||||
|
<text x="230" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Recursive Language Models · 38 Tests · 17k+ LOC</text>
|
||||||
|
|
||||||
|
<!-- RLM sub-components as mini pills -->
|
||||||
|
<g transform="translate(75, 435)">
|
||||||
|
<!-- Chunking -->
|
||||||
|
<rect x="0" y="0" width="80" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="40" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Chunking</text>
|
||||||
|
<!-- Hybrid Search -->
|
||||||
|
<rect x="90" y="0" width="95" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="137" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Hybrid Search</text>
|
||||||
|
<!-- Dispatcher -->
|
||||||
|
<rect x="195" y="0" width="80" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="235" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Dispatcher</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(75, 465)">
|
||||||
|
<!-- BM25 -->
|
||||||
|
<rect x="0" y="0" width="65" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="32" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">BM25</text>
|
||||||
|
<!-- Semantic -->
|
||||||
|
<rect x="75" y="0" width="70" height="20" rx="3" fill="rgba(168,85,247,0.08)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="110" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Semantic</text>
|
||||||
|
<!-- RRF -->
|
||||||
|
<rect x="155" y="0" width="50" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="180" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">RRF</text>
|
||||||
|
<!-- Sandbox -->
|
||||||
|
<rect x="215" y="0" width="60" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="245" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Sandbox</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Animated search indicator -->
|
||||||
|
<g transform="translate(370, 400)">
|
||||||
|
<circle r="6" fill="none" stroke="#22d3ee" stroke-width="0.8" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="4;8;4" dur="3s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.4;0.1;0.4" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle r="3" fill="#22d3ee" opacity="0.07">
|
||||||
|
<animate attributeName="opacity" values="0.2;0.5;0.2" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- LLM Router -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="500" y="380" width="380" height="130" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="504" y="380" width="372" height="2" rx="1" fill="#a855f7" opacity="0.7"/>
|
||||||
|
<text x="690" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#a855f7" text-anchor="middle" filter="url(#glow-sm)">Multi-IA LLM Router</text>
|
||||||
|
<text x="690" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Budget Enforcement · Cost Tracking · 53 Tests</text>
|
||||||
|
|
||||||
|
<!-- Router sub-components -->
|
||||||
|
<g transform="translate(515, 435)">
|
||||||
|
<rect x="0" y="0" width="95" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="47" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Rule Router</text>
|
||||||
|
<rect x="105" y="0" width="115" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="162" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Budget Manager</text>
|
||||||
|
<rect x="230" y="0" width="110" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="285" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Cost Tracker</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(515, 465)">
|
||||||
|
<rect x="0" y="0" width="95" height="20" rx="3" fill="rgba(168,85,247,0.08)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="47" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Fallback Chain</text>
|
||||||
|
<rect x="105" y="0" width="90" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="150" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Cost Ranker</text>
|
||||||
|
<rect x="205" y="0" width="80" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="245" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Providers</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Routing indicator animation -->
|
||||||
|
<g transform="translate(855, 400)">
|
||||||
|
<line x1="-6" y1="0" x2="6" y2="0" stroke="#a855f7" stroke-width="1.5" opacity="0.5">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="4s" repeatCount="indefinite"/>
|
||||||
|
</line>
|
||||||
|
<line x1="0" y1="-6" x2="0" y2="6" stroke="#ec4899" stroke-width="1.5" opacity="0.5">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="4s" repeatCount="indefinite"/>
|
||||||
|
</line>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Swarm Coordinator -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="980" y="380" width="310" height="130" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="984" y="380" width="302" height="1.5" rx="1" fill="#ec4899" opacity="0.6"/>
|
||||||
|
<text x="1135" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#ec4899" text-anchor="middle" filter="url(#glow-sm)">Swarm Coordinator</text>
|
||||||
|
<text x="1135" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Load Balancing · Prometheus · 6 Tests</text>
|
||||||
|
|
||||||
|
<g transform="translate(995, 435)">
|
||||||
|
<rect x="0" y="0" width="90" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="45" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Assignment</text>
|
||||||
|
<rect x="100" y="0" width="90" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="145" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Filtering</text>
|
||||||
|
<rect x="200" y="0" width="80" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="240" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Metrics</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(995, 465)">
|
||||||
|
<rect x="0" y="0" width="130" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="65" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">success_rate / (1+load)</text>
|
||||||
|
<rect x="140" y="0" width="80" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="180" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Capabilities</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Swarm pulse -->
|
||||||
|
<circle cx="1270" cy="395" r="3" fill="#ec4899" opacity="0.04">
|
||||||
|
<animate attributeName="r" values="2;5;2" dur="2s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.2;0.5;0.2" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- RLM → LLM Router connection -->
|
||||||
|
<path id="path-rlm-llm" d="M 400 445 L 500 445" fill="none" stroke="url(#grad-cyan-purple)" stroke-width="3" stroke-opacity="0.3"/>
|
||||||
|
<use href="#particle-cyan" opacity="0.7"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 400 445 L 500 445"/></use>
|
||||||
|
|
||||||
|
<!-- LLM Router → Swarm connection -->
|
||||||
|
<path d="M 880 445 L 980 445" fill="none" stroke="url(#grad-purple-pink)" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.6"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 880 445 L 980 445"/></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Intelligence → Data -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- RLM → KG -->
|
||||||
|
<path id="path-rlm-kg" d="M 160 510 L 160 575" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 160 510 L 160 575"/></use>
|
||||||
|
|
||||||
|
<!-- RLM → SurrealDB -->
|
||||||
|
<path id="path-rlm-sdb" d="M 300 510 L 300 540 Q 300 555 400 555 L 530 555 Q 545 555 545 575" fill="none" stroke="#22d3ee" stroke-width="2.4" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-cyan" opacity="0.7"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-rlm-sdb"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- LLM Router → Providers (goes down below data) -->
|
||||||
|
<path id="path-llm-providers" d="M 790 510 L 790 725" fill="none" stroke="#a855f7" stroke-width="3" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-purple" opacity="0.8"><animateMotion dur="3s" repeatCount="indefinite" path="M 790 510 L 790 725"/></use>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.5"><animateMotion dur="3s" begin="1.5s" repeatCount="indefinite" path="M 790 510 L 790 725"/></use>
|
||||||
|
|
||||||
|
<!-- Swarm → NATS -->
|
||||||
|
<path id="path-sw-nats" d="M 1135 510 L 1135 575" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 1135 510 L 1135 575"/></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 4: DATA LAYER (y=575) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Knowledge Graph -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="60" y="575" width="260" height="100" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="1"/>
|
||||||
|
<rect x="60" y="575" width="260" height="1.5" rx="1" fill="#22d3ee" opacity="0.5"/>
|
||||||
|
<text x="190" y="600" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Knowledge Graph</text>
|
||||||
|
<text x="190" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.7" text-anchor="middle">Temporal History · Learning Curves · 20 Tests</text>
|
||||||
|
<g transform="translate(75, 630)">
|
||||||
|
<rect x="0" y="0" width="80" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="40" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Executions</text>
|
||||||
|
<rect x="90" y="0" width="70" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="125" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Similarity</text>
|
||||||
|
<rect x="170" y="0" width="60" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="200" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Causal</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SurrealDB -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="420" y="575" width="340" height="100" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="420" y="575" width="340" height="2" rx="1" fill="url(#grad-main)" opacity="0.6"/>
|
||||||
|
<text x="590" y="600" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="url(#grad-main)" text-anchor="middle" filter="url(#glow-sm)">SurrealDB</text>
|
||||||
|
<text x="590" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Multi-Model Database · Multi-Tenant Scopes</text>
|
||||||
|
|
||||||
|
<g transform="translate(435, 630)">
|
||||||
|
<rect x="0" y="0" width="65" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="32" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Projects</text>
|
||||||
|
<rect x="75" y="0" width="50" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="100" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Tasks</text>
|
||||||
|
<rect x="135" y="0" width="55" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="162" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Agents</text>
|
||||||
|
<rect x="200" y="0" width="55" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="227" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Chunks</text>
|
||||||
|
<rect x="265" y="0" width="45" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="287" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">A2A</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- DB activity indicator -->
|
||||||
|
<g transform="translate(735, 590)">
|
||||||
|
<rect x="0" y="0" width="2" height="10" fill="#22d3ee" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="6;12;6" dur="1.2s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="5" y="0" width="2" height="8" fill="#a855f7" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="8;14;8" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="10" y="0" width="2" height="12" fill="#ec4899" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="10;16;10" dur="1s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- KG → SurrealDB -->
|
||||||
|
<line x1="320" y1="630" x2="420" y2="630" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 320 630 L 420 630"/></use>
|
||||||
|
|
||||||
|
<!-- NATS JetStream -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="860" y="575" width="340" height="100" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="860" y="575" width="340" height="1.5" rx="1" fill="#ec4899" opacity="0.5"/>
|
||||||
|
<text x="1030" y="600" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#ec4899" text-anchor="middle" filter="url(#glow-sm)">NATS JetStream</text>
|
||||||
|
<text x="1030" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Message Queue · Async Coordination · Pub/Sub</text>
|
||||||
|
|
||||||
|
<g transform="translate(875, 630)">
|
||||||
|
<rect x="0" y="0" width="75" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="37" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Agent Jobs</text>
|
||||||
|
<rect x="85" y="0" width="75" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="122" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Workflows</text>
|
||||||
|
<rect x="170" y="0" width="70" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="205" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Proposals</text>
|
||||||
|
<rect x="250" y="0" width="60" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="280" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">A2A</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Message pulse animation -->
|
||||||
|
<g transform="translate(1125, 590)">
|
||||||
|
<circle r="4" fill="none" stroke="#22d3ee" stroke-width="1.5" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="3;8;3" dur="2s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="1;0.4;1" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle r="2" fill="#22d3ee" opacity="0.07">
|
||||||
|
<animate attributeName="opacity" values="0.7;1;0.7" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SurrealDB ↔ NATS bridge line -->
|
||||||
|
<line x1="760" y1="625" x2="860" y2="625" stroke="url(#grad-purple-pink)" stroke-width="0.8" stroke-opacity="0.4" stroke-dasharray="4 3"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Data → Providers -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Central provider trunk (from LLM Router, already drawn) -->
|
||||||
|
<!-- Branch to each provider -->
|
||||||
|
<path id="path-to-claude" d="M 790 725 Q 790 750 500 750 L 245 750 Q 225 750 225 785" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-to-claude"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-openai" d="M 790 725 Q 790 760 600 760 L 555 760 Q 545 760 545 785" fill="none" stroke="#a855f7" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.6"><animateMotion dur="2s" repeatCount="indefinite"><mpath href="#path-to-openai"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-gemini" d="M 790 725 Q 790 770 810 770 L 855 770 Q 865 770 865 785" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.6"><animateMotion dur="2.2s" repeatCount="indefinite"><mpath href="#path-to-gemini"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-ollama" d="M 790 725 Q 790 750 900 750 L 1155 750 Q 1175 750 1175 785" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="2.8s" repeatCount="indefinite"><mpath href="#path-to-ollama"/></animateMotion></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 5: LLM PROVIDERS (y=810) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Claude -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="100" y="785" width="250" height="55" rx="6" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="225" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Anthropic Claude</text>
|
||||||
|
<text x="225" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.7" text-anchor="middle">Opus · Sonnet · Haiku</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- OpenAI -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="420" y="785" width="250" height="55" rx="6" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="545" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#a855f7" text-anchor="middle">OpenAI</text>
|
||||||
|
<text x="545" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.7" text-anchor="middle">GPT-4 · GPT-4o · GPT-3.5</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Gemini -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="740" y="785" width="250" height="55" rx="6" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="865" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#ec4899" text-anchor="middle">Google Gemini</text>
|
||||||
|
<text x="865" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.7" text-anchor="middle">2.0 Pro · Flash · 1.5 Pro</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Ollama -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="1060" y="785" width="250" height="55" rx="6" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="1185" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Ollama (Local)</text>
|
||||||
|
<text x="1185" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.7" text-anchor="middle">Llama · Mistral · CodeLlama</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- SUPPORTING CRATES (bottom strip) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<g transform="translate(0, 882)">
|
||||||
|
<rect x="60" y="0" width="1280" height="50" rx="6" fill="rgba(168,85,247,0.04)" stroke="#a855f7" stroke-opacity="0.1" stroke-width="0.5"/>
|
||||||
|
<text x="700" y="16" font-family="'JetBrains Mono', monospace" font-size="9" fill="#a855f7" opacity="0.7" text-anchor="middle" letter-spacing="2">SUPPORTING CRATES</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="10" opacity="0.6" text-anchor="middle">
|
||||||
|
<text x="130" y="36" fill="#22d3ee">vapora-shared</text>
|
||||||
|
<text x="260" y="36" fill="#a855f7">vapora-tracking</text>
|
||||||
|
<text x="400" y="36" fill="#ec4899">vapora-telemetry</text>
|
||||||
|
<text x="540" y="36" fill="#22d3ee">vapora-analytics</text>
|
||||||
|
<text x="680" y="36" fill="#a855f7">vapora-worktree</text>
|
||||||
|
<text x="820" y="36" fill="#ec4899">vapora-doc-lifecycle</text>
|
||||||
|
<text x="975" y="36" fill="#22d3ee">vapora-workflow-engine</text>
|
||||||
|
<text x="1140" y="36" fill="#a855f7">vapora-cli</text>
|
||||||
|
<text x="1250" y="36" fill="#ec4899">vapora-leptos-ui</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- OBSERVABILITY STRIP (right edge) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<g transform="translate(1340, 80)">
|
||||||
|
<rect x="0" y="0" width="4" height="790" rx="2" fill="url(#grad-vertical)" opacity="0.3">
|
||||||
|
<animate attributeName="opacity" values="0.2;0.4;0.2" dur="5s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<text x="15" y="400" font-family="'JetBrains Mono', monospace" font-size="9" fill="#a855f7" opacity="0.6" letter-spacing="2" text-anchor="middle" transform="rotate(90 15 400)">PROMETHEUS · GRAFANA · OPENTELEMETRY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- FOOTER -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<text x="700" y="970" font-family="'JetBrains Mono', monospace" font-size="11" font-weight="700" fill="url(#grad-main)" text-anchor="middle" opacity="0.7" letter-spacing="3">VAPORA v1.2.0</text>
|
||||||
|
<text x="700" y="993" font-family="'Inter', sans-serif" font-size="9" fill="#a855f7" opacity="0.6" text-anchor="middle" letter-spacing="1">Evaporate complexity · Full-Stack Rust · Production Ready</text>
|
||||||
|
|
||||||
|
<!-- Bottom gradient bar -->
|
||||||
|
<rect x="400" y="1005" width="600" height="2" rx="1" fill="url(#grad-main)" opacity="0.3"/>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 42 KiB |
1
assets/web/architecture-diagram.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<!doctype html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>VAPORA — Architecture</title><style> @import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700;800&family=Inter:wght@300;400;500;600;700&display=swap");:root{--bg-primary:#0a0a0a;--text-primary:#c8ccd4;--border-light:rgba(255,255,255,0.1);--border-color:rgba(34,211,238,0.3);}html.light-mode{--bg-primary:#ffffff;--text-primary:#1a1a1a;--border-light:rgba(0,0,0,0.1);--border-color:rgba(0,0,0,0.1);}*{margin:0;padding:0;box-sizing:border-box;}body{background:var(--bg-primary);color:var(--text-primary);font-family:"Inter",sans-serif;min-height:100vh;display:flex;align-items:center;justify-content:center;overflow:hidden;transition:background-color 0.3s ease,color 0.3s ease;}.diagram-container{width:1400px;height:1020px;position:relative;display:inline-block;}svg{width:100%;height:100%;}.nav-toggle{position:fixed;top:2rem;right:2rem;z-index:100;display:flex;gap:0.5rem;background:var(--bg-primary);border:1px solid var(--border-color);border-radius:20px;padding:0.3rem 0.3rem;backdrop-filter:blur(10px);box-shadow:0 8px 32px rgba(0,0,0,0.1);}.nav-btn{background:transparent;border:none;color:#94a3b8;padding:0.5rem 1rem;border-radius:18px;cursor:pointer;font-weight:700;font-size:0.85rem;text-transform:uppercase;transition:all 0.3s ease;font-family:"JetBrains Mono",monospace;text-decoration:none;display:inline-block;}.nav-btn.active{background:linear-gradient(135deg,#22d3ee 0%,#a855f7 100%);color:#fff;}.nav-btn:hover{color:#22d3ee;}.theme-toggle{background:transparent;border:none;color:var(--text-primary);padding:0.5rem 1rem;border-radius:18px;cursor:pointer;font-weight:700;font-size:1.2rem;transition:all 0.3s ease;}.theme-toggle:hover{color:#22d3ee;}@media (max-width:768px){.nav-toggle{top:1rem;right:1rem;}.diagram-container{width:100vw;height:auto;}}</style></head><body><div class="nav-toggle"><button style="display: none" class="nav-btn active" data-lang="en" onclick="switchLanguage('en')" > EN </button><button style="display: none" class="nav-btn" data-lang="es" onclick="switchLanguage('es')" > ES </button><button class="theme-toggle" onclick="toggleTheme()" title="Toggle light/dark mode" ><span id="theme-icon">🌙</span></button><a href="index.html" class="nav-btn" style=" background: rgba(34, 211, 238, 0.2); border: 1px solid rgba(34, 211, 238, 0.5); " >← VAPORA</a ></div><div class="diagram-container"><img id="dark-svg" src="vapora_architecture.svg" alt="VAPORA Architecture - Dark Mode" style="width: 100%; height: 100%; display: block" /><img id="light-svg" src="vapora_architecture_white.svg" alt="VAPORA Architecture - Light Mode" style="width: 100%; height: 100%; display: none" /></div><script> const LANG_KEY = "vapora-arch-lang";function getCurrentLanguage(){return localStorage.getItem(LANG_KEY)|| "en";}function switchLanguage(lang){localStorage.setItem(LANG_KEY,lang);document .querySelectorAll(".nav-btn[data-lang]").forEach((btn)=>{btn.classList.remove("active");if(btn.dataset.lang === lang){btn.classList.add("active");}});document .querySelectorAll("[data-en][data-es]").forEach((el)=>{const content = el.dataset[lang];el.textContent = content;});document.documentElement.lang = lang;}document.addEventListener("DOMContentLoaded",()=>{const currentLang = getCurrentLanguage();switchLanguage(currentLang);const currentTheme = getTheme();setTheme(currentTheme);});const THEME_KEY = "vapora-theme";function getTheme(){return localStorage.getItem(THEME_KEY)|| "dark";}function setTheme(theme){localStorage.setItem(THEME_KEY,theme);const html = document.documentElement;const icon = document.getElementById("theme-icon");const darkSvg = document.getElementById("dark-svg");const lightSvg = document.getElementById("light-svg");if(theme === "light"){html.classList.add("light-mode");icon.textContent = "🌙";if(darkSvg)darkSvg.style.display = "none";if(lightSvg)lightSvg.style.display = "block";}else{html.classList.remove("light-mode");icon.textContent = "☀️";if(darkSvg)darkSvg.style.display = "block";if(lightSvg)lightSvg.style.display = "none";}}function toggleTheme(){const currentTheme = getTheme();const newTheme = currentTheme === "dark" ? "light" : "dark";setTheme(newTheme);}</script></body></html>
|
||||||
250
assets/web/src/architecture-diagram.html
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>VAPORA — Architecture</title>
|
||||||
|
<style>
|
||||||
|
@import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700;800&family=Inter:wght@300;400;500;600;700&display=swap");
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--bg-primary: #0a0a0a;
|
||||||
|
--text-primary: #c8ccd4;
|
||||||
|
--border-light: rgba(255, 255, 255, 0.1);
|
||||||
|
--border-color: rgba(34, 211, 238, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
html.light-mode {
|
||||||
|
--bg-primary: #ffffff;
|
||||||
|
--text-primary: #1a1a1a;
|
||||||
|
--border-light: rgba(0, 0, 0, 0.1);
|
||||||
|
--border-color: rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: var(--bg-primary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-family: "Inter", sans-serif;
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
transition:
|
||||||
|
background-color 0.3s ease,
|
||||||
|
color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diagram-container {
|
||||||
|
width: 1400px;
|
||||||
|
height: 1020px;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Navigation Menu */
|
||||||
|
.nav-toggle {
|
||||||
|
position: fixed;
|
||||||
|
top: 2rem;
|
||||||
|
right: 2rem;
|
||||||
|
z-index: 100;
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 0.3rem 0.3rem;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-btn {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #94a3b8;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: 18px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
font-family: "JetBrains Mono", monospace;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-btn.active {
|
||||||
|
background: linear-gradient(135deg, #22d3ee 0%, #a855f7 100%);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-btn:hover {
|
||||||
|
color: #22d3ee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: var(--text-primary);
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: 18px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle:hover {
|
||||||
|
color: #22d3ee;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.nav-toggle {
|
||||||
|
top: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
}
|
||||||
|
.diagram-container {
|
||||||
|
width: 100vw;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="nav-toggle">
|
||||||
|
<button
|
||||||
|
style="display: none"
|
||||||
|
class="nav-btn active"
|
||||||
|
data-lang="en"
|
||||||
|
onclick="switchLanguage('en')"
|
||||||
|
>
|
||||||
|
EN
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
style="display: none"
|
||||||
|
class="nav-btn"
|
||||||
|
data-lang="es"
|
||||||
|
onclick="switchLanguage('es')"
|
||||||
|
>
|
||||||
|
ES
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="theme-toggle"
|
||||||
|
onclick="toggleTheme()"
|
||||||
|
title="Toggle light/dark mode"
|
||||||
|
>
|
||||||
|
<span id="theme-icon">🌙</span>
|
||||||
|
</button>
|
||||||
|
<a
|
||||||
|
href="index.html"
|
||||||
|
class="nav-btn"
|
||||||
|
style="
|
||||||
|
background: rgba(34, 211, 238, 0.2);
|
||||||
|
border: 1px solid rgba(34, 211, 238, 0.5);
|
||||||
|
"
|
||||||
|
>← VAPORA</a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="diagram-container">
|
||||||
|
<img
|
||||||
|
id="dark-svg"
|
||||||
|
src="vapora_architecture.svg"
|
||||||
|
alt="VAPORA Architecture - Dark Mode"
|
||||||
|
style="width: 100%; height: 100%; display: block"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
id="light-svg"
|
||||||
|
src="vapora_architecture_white.svg"
|
||||||
|
alt="VAPORA Architecture - Light Mode"
|
||||||
|
style="width: 100%; height: 100%; display: none"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Language management
|
||||||
|
const LANG_KEY = "vapora-arch-lang";
|
||||||
|
|
||||||
|
function getCurrentLanguage() {
|
||||||
|
return localStorage.getItem(LANG_KEY) || "en";
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchLanguage(lang) {
|
||||||
|
localStorage.setItem(LANG_KEY, lang);
|
||||||
|
|
||||||
|
// Update language buttons
|
||||||
|
document
|
||||||
|
.querySelectorAll(".nav-btn[data-lang]")
|
||||||
|
.forEach((btn) => {
|
||||||
|
btn.classList.remove("active");
|
||||||
|
if (btn.dataset.lang === lang) {
|
||||||
|
btn.classList.add("active");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update all translatable elements
|
||||||
|
document
|
||||||
|
.querySelectorAll("[data-en][data-es]")
|
||||||
|
.forEach((el) => {
|
||||||
|
const content = el.dataset[lang];
|
||||||
|
el.textContent = content;
|
||||||
|
});
|
||||||
|
|
||||||
|
document.documentElement.lang = lang;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize language on page load
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
const currentLang = getCurrentLanguage();
|
||||||
|
switchLanguage(currentLang);
|
||||||
|
const currentTheme = getTheme();
|
||||||
|
setTheme(currentTheme);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Theme management
|
||||||
|
const THEME_KEY = "vapora-theme";
|
||||||
|
|
||||||
|
function getTheme() {
|
||||||
|
return localStorage.getItem(THEME_KEY) || "dark";
|
||||||
|
}
|
||||||
|
|
||||||
|
function setTheme(theme) {
|
||||||
|
localStorage.setItem(THEME_KEY, theme);
|
||||||
|
const html = document.documentElement;
|
||||||
|
const icon = document.getElementById("theme-icon");
|
||||||
|
const darkSvg = document.getElementById("dark-svg");
|
||||||
|
const lightSvg = document.getElementById("light-svg");
|
||||||
|
|
||||||
|
if (theme === "light") {
|
||||||
|
html.classList.add("light-mode");
|
||||||
|
icon.textContent = "🌙";
|
||||||
|
if (darkSvg) darkSvg.style.display = "none";
|
||||||
|
if (lightSvg) lightSvg.style.display = "block";
|
||||||
|
} else {
|
||||||
|
html.classList.remove("light-mode");
|
||||||
|
icon.textContent = "☀️";
|
||||||
|
if (darkSvg) darkSvg.style.display = "block";
|
||||||
|
if (lightSvg) lightSvg.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleTheme() {
|
||||||
|
const currentTheme = getTheme();
|
||||||
|
const newTheme = currentTheme === "dark" ? "light" : "dark";
|
||||||
|
setTheme(newTheme);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
576
assets/web/src/vapora_architecture.svg
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 1020" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700;800&family=Inter:wght@400;500;600&display=swap');
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Brand gradients -->
|
||||||
|
<linearGradient id="grad-main" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee"/>
|
||||||
|
<stop offset="50%" stop-color="#a855f7"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-cyan-purple" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee"/>
|
||||||
|
<stop offset="100%" stop-color="#a855f7"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-purple-pink" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#a855f7"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-vertical" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.8"/>
|
||||||
|
<stop offset="50%" stop-color="#a855f7" stop-opacity="0.5"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899" stop-opacity="0.3"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-cyan" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.15"/>
|
||||||
|
<stop offset="100%" stop-color="#22d3ee" stop-opacity="0.05"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-purple" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#a855f7" stop-opacity="0.15"/>
|
||||||
|
<stop offset="100%" stop-color="#a855f7" stop-opacity="0.05"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-pink" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#ec4899" stop-opacity="0.15"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899" stop-opacity="0.05"/>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Glow filters -->
|
||||||
|
<filter id="glow-sm">
|
||||||
|
<feGaussianBlur stdDeviation="2" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glow-md">
|
||||||
|
<feGaussianBlur stdDeviation="4" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glow-lg">
|
||||||
|
<feGaussianBlur stdDeviation="6" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glass-card">
|
||||||
|
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"/>
|
||||||
|
<feOffset dx="0" dy="1" result="shadow"/>
|
||||||
|
<feFlood flood-color="#000" flood-opacity="0.3" result="color"/>
|
||||||
|
<feComposite in="color" in2="shadow" operator="in" result="shadow"/>
|
||||||
|
<feMerge><feMergeNode in="shadow"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Animated particle marker -->
|
||||||
|
<circle id="particle-cyan" r="3" fill="#22d3ee" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-purple" r="3" fill="#a855f7" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-pink" r="3" fill="#ec4899" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-sm-cyan" r="2" fill="#22d3ee" filter="url(#glow-sm)"/>
|
||||||
|
<circle id="particle-sm-purple" r="2" fill="#a855f7" filter="url(#glow-sm)"/>
|
||||||
|
<circle id="particle-sm-pink" r="2" fill="#ec4899" filter="url(#glow-sm)"/>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- BACKGROUND -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<rect width="1400" height="1020" fill="#0a0a0a"/>
|
||||||
|
|
||||||
|
<!-- Subtle tech grid -->
|
||||||
|
<g opacity="0.04" stroke="#22d3ee" stroke-width="0.5">
|
||||||
|
<line x1="0" y1="0" x2="1400" y2="0"><animate attributeName="y1" values="0;1020" dur="60s" repeatCount="indefinite"/><animate attributeName="y2" values="0;1020" dur="60s" repeatCount="indefinite"/></line>
|
||||||
|
<line x1="100" y1="0" x2="100" y2="1020"/>
|
||||||
|
<line x1="250" y1="0" x2="250" y2="1020"/>
|
||||||
|
<line x1="400" y1="0" x2="400" y2="1020"/>
|
||||||
|
<line x1="550" y1="0" x2="550" y2="1020"/>
|
||||||
|
<line x1="700" y1="0" x2="700" y2="1020"/>
|
||||||
|
<line x1="850" y1="0" x2="850" y2="1020"/>
|
||||||
|
<line x1="1000" y1="0" x2="1000" y2="1020"/>
|
||||||
|
<line x1="1150" y1="0" x2="1150" y2="1020"/>
|
||||||
|
<line x1="1300" y1="0" x2="1300" y2="1020"/>
|
||||||
|
<line x1="0" y1="130" x2="1400" y2="130"/>
|
||||||
|
<line x1="0" y1="260" x2="1400" y2="260"/>
|
||||||
|
<line x1="0" y1="420" x2="1400" y2="420"/>
|
||||||
|
<line x1="0" y1="580" x2="1400" y2="580"/>
|
||||||
|
<line x1="0" y1="720" x2="1400" y2="720"/>
|
||||||
|
<line x1="0" y1="860" x2="1400" y2="860"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Ambient glow orbs -->
|
||||||
|
<circle cx="240" cy="350" r="180" fill="#22d3ee" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="160;200;160" dur="8s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="690" cy="360" r="175" fill="#a855f7" opacity="0.05">
|
||||||
|
<animate attributeName="r" values="175;195;175" dur="10s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="1130" cy="350" r="200" fill="#ec4899" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="180;220;180" dur="9s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- TITLE -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<text x="700" y="42" font-family="'JetBrains Mono', monospace" font-size="22" font-weight="800" fill="url(#grad-main)" letter-spacing="6" text-anchor="middle" filter="url(#glow-sm)">VAPORA ARCHITECTURE</text>
|
||||||
|
<text x="700" y="62" font-family="'Inter', sans-serif" font-size="11" fill="#a855f7" opacity="0.6" letter-spacing="3" text-anchor="middle">18 CRATES · 354 TESTS · 100% RUST</text>
|
||||||
|
|
||||||
|
<!-- Layer labels (left side) -->
|
||||||
|
<text x="30" y="115" font-family="'JetBrains Mono', monospace" font-size="10" fill="#22d3ee" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 115)">PRESENTATION</text>
|
||||||
|
<text x="30" y="290" font-family="'JetBrains Mono', monospace" font-size="10" fill="#a855f7" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 290)">SERVICES</text>
|
||||||
|
<text x="30" y="485" font-family="'JetBrains Mono', monospace" font-size="10" fill="#ec4899" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 485)">INTELLIGENCE</text>
|
||||||
|
<text x="30" y="640" font-family="'JetBrains Mono', monospace" font-size="10" fill="#22d3ee" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 640)">DATA</text>
|
||||||
|
<text x="30" y="850" font-family="'JetBrains Mono', monospace" font-size="10" fill="#a855f7" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 850)">PROVIDERS</text>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 1: FRONTEND (y=80) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Frontend card -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="490" y="80" width="420" height="65" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.4" stroke-width="2"/>
|
||||||
|
<rect x="494" y="80" width="412" height="1.5" rx="1" fill="url(#grad-main)" opacity="0.8"/>
|
||||||
|
<text x="700" y="106" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#22d3ee" text-anchor="middle" filter="url(#glow-sm)">Leptos WASM Frontend</text>
|
||||||
|
<text x="700" y="124" font-family="'Inter', sans-serif" font-size="10" fill="#ffffff" opacity="0.5" text-anchor="middle">Kanban Board · Glassmorphism UI · UnoCSS · Reactive Components</text>
|
||||||
|
<!-- Pulse ring -->
|
||||||
|
<rect x="490" y="80" width="420" height="65" rx="8" fill="none" stroke="#22d3ee" stroke-opacity="0.15">
|
||||||
|
<animate attributeName="stroke-opacity" values="0.15;0.3;0.15" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTION: Frontend → Services -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Frontend to Backend -->
|
||||||
|
<path id="path-fe-be" d="M 580 145 L 580 160 Q 580 175 480 175 L 280 175 Q 260 175 260 195 L 260 210" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.8"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-fe-be"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- Frontend to Agents -->
|
||||||
|
<line x1="700" y1="145" x2="700" y2="210" stroke="#a855f7" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.8"><animateMotion dur="2s" repeatCount="indefinite" path="M 700 145 L 700 210"/></use>
|
||||||
|
|
||||||
|
<!-- Frontend to MCP -->
|
||||||
|
<path id="path-fe-mcp" d="M 820 145 L 820 160 Q 820 175 920 175 L 1100 175 Q 1140 175 1140 195 L 1140 210" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.8"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-fe-mcp"/></animateMotion></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 2: SERVICES (y=210) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Backend / Axum API -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="100" y="210" width="310" height="100" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="104" y="210" width="302" height="1.5" rx="1" fill="#22d3ee" opacity="0.6"/>
|
||||||
|
<text x="255" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#22d3ee" text-anchor="middle">Axum Backend API</text>
|
||||||
|
<text x="255" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">40+ REST Endpoints · 161 Tests</text>
|
||||||
|
<!-- Sub-items -->
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.35">
|
||||||
|
<text x="120" y="278">Projects</text>
|
||||||
|
<text x="180" y="278">Tasks</text>
|
||||||
|
<text x="225" y="278">Agents</text>
|
||||||
|
<text x="280" y="278">Workflows</text>
|
||||||
|
<text x="350" y="278">Proposals</text>
|
||||||
|
<text x="120" y="294">Swarm</text>
|
||||||
|
<text x="175" y="294">Metrics</text>
|
||||||
|
<text x="235" y="294">RLM API</text>
|
||||||
|
<text x="300" y="294">WebSocket</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Agent Runtime -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="540" y="210" width="310" height="100" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="544" y="210" width="302" height="1.5" rx="1" fill="#a855f7" opacity="0.6"/>
|
||||||
|
<text x="695" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#a855f7" text-anchor="middle">Agent Runtime</text>
|
||||||
|
<text x="695" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Orchestration · Learning Profiles · 71 Tests</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.35">
|
||||||
|
<text x="560" y="278">Registry</text>
|
||||||
|
<text x="625" y="278">Coordinator</text>
|
||||||
|
<text x="720" y="278">Scoring</text>
|
||||||
|
<text x="785" y="278">Profiles</text>
|
||||||
|
<text x="560" y="294">12 Roles</text>
|
||||||
|
<text x="630" y="294">Health Checks</text>
|
||||||
|
<text x="735" y="294">Recency Bias</text>
|
||||||
|
</g>
|
||||||
|
<!-- Heartbeat animation -->
|
||||||
|
<circle cx="835" cy="225" r="4" fill="#a855f7" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="3;5;3" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.3;0.6;0.3" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- MCP Gateway -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="980" y="210" width="310" height="100" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="984" y="210" width="302" height="1.5" rx="1" fill="#ec4899" opacity="0.6"/>
|
||||||
|
<text x="1135" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#ec4899" text-anchor="middle">MCP Gateway</text>
|
||||||
|
<text x="1135" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Model Context Protocol · Plugin System</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.35">
|
||||||
|
<text x="1000" y="278">Stdio Transport</text>
|
||||||
|
<text x="1105" y="278">SSE Transport</text>
|
||||||
|
<text x="1210" y="278">JSON-RPC</text>
|
||||||
|
<text x="1000" y="294">6 Tools</text>
|
||||||
|
<text x="1060" y="294">Tool Registry</text>
|
||||||
|
<text x="1160" y="294">Schema Validation</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- A2A Protocol (small card overlapping) -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="445" y="280" width="86" height="35" rx="6" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="488" y="300" font-family="'JetBrains Mono', monospace" font-size="9" font-weight="700" fill="#a855f7" opacity="0.6" text-anchor="middle">A2A Protocol</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Services → Intelligence -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Backend → RLM -->
|
||||||
|
<path id="path-be-rlm" d="M 200 310 L 200 380" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 200 310 L 200 380"/></use>
|
||||||
|
|
||||||
|
<!-- Backend → SurrealDB (arco por la derecha para evitar KG) -->
|
||||||
|
<path id="path-be-sdb" d="M 320 310 L 320 340 Q 320 360 360 360 L 420 360 Q 435 360 435 380 Q 435 580 420 580 L 420 585" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.35" stroke-dasharray="4 4"/>
|
||||||
|
|
||||||
|
<!-- Agents → LLM Router -->
|
||||||
|
<line x1="695" y1="310" x2="695" y2="380" stroke="#a855f7" stroke-width="2.4" stroke-opacity="0.3"/>
|
||||||
|
<use href="#particle-purple" opacity="0.8"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 695 310 L 695 380"/></use>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.5"><animateMotion dur="1.5s" begin="0.75s" repeatCount="indefinite" path="M 695 310 L 695 380"/></use>
|
||||||
|
|
||||||
|
<!-- Agents → Swarm -->
|
||||||
|
<path id="path-ag-sw" d="M 800 310 L 800 340 Q 800 355 900 355 L 1050 355 Q 1070 355 1070 375 L 1070 380" fill="none" stroke="#a855f7" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.6"><animateMotion dur="2.2s" repeatCount="indefinite"><mpath href="#path-ag-sw"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- MCP → Agents -->
|
||||||
|
<path id="path-mcp-ag" d="M 1020 310 L 1020 320 Q 1020 332 920 332 L 810 332 Q 800 332 800 320 L 800 310" fill="none" stroke="#ec4899" stroke-width="1.6" stroke-opacity="0.35" stroke-dasharray="3 3"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 3: INTELLIGENCE (y=380) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- RLM Engine -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="60" y="380" width="340" height="130" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="64" y="380" width="332" height="2" rx="1" fill="url(#grad-main)" opacity="0.7"/>
|
||||||
|
<text x="230" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="url(#grad-main)" text-anchor="middle" filter="url(#glow-sm)">RLM Engine</text>
|
||||||
|
<text x="230" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Recursive Language Models · 38 Tests · 17k+ LOC</text>
|
||||||
|
|
||||||
|
<!-- RLM sub-components as mini pills -->
|
||||||
|
<g transform="translate(75, 435)">
|
||||||
|
<!-- Chunking -->
|
||||||
|
<rect x="0" y="0" width="80" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="40" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Chunking</text>
|
||||||
|
<!-- Hybrid Search -->
|
||||||
|
<rect x="90" y="0" width="95" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="137" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Hybrid Search</text>
|
||||||
|
<!-- Dispatcher -->
|
||||||
|
<rect x="195" y="0" width="80" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="235" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Dispatcher</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(75, 465)">
|
||||||
|
<!-- BM25 -->
|
||||||
|
<rect x="0" y="0" width="65" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="32" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">BM25</text>
|
||||||
|
<!-- Semantic -->
|
||||||
|
<rect x="75" y="0" width="70" height="20" rx="3" fill="rgba(168,85,247,0.08)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="110" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Semantic</text>
|
||||||
|
<!-- RRF -->
|
||||||
|
<rect x="155" y="0" width="50" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="180" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">RRF</text>
|
||||||
|
<!-- Sandbox -->
|
||||||
|
<rect x="215" y="0" width="60" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="245" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Sandbox</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Animated search indicator -->
|
||||||
|
<g transform="translate(370, 400)">
|
||||||
|
<circle r="6" fill="none" stroke="#22d3ee" stroke-width="0.8" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="4;8;4" dur="3s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.4;0.1;0.4" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle r="3" fill="#22d3ee" opacity="0.07">
|
||||||
|
<animate attributeName="opacity" values="0.2;0.5;0.2" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- LLM Router -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="500" y="380" width="380" height="130" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="504" y="380" width="372" height="2" rx="1" fill="#a855f7" opacity="0.7"/>
|
||||||
|
<text x="690" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#a855f7" text-anchor="middle" filter="url(#glow-sm)">Multi-IA LLM Router</text>
|
||||||
|
<text x="690" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Budget Enforcement · Cost Tracking · 53 Tests</text>
|
||||||
|
|
||||||
|
<!-- Router sub-components -->
|
||||||
|
<g transform="translate(515, 435)">
|
||||||
|
<rect x="0" y="0" width="95" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="47" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Rule Router</text>
|
||||||
|
<rect x="105" y="0" width="115" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="162" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Budget Manager</text>
|
||||||
|
<rect x="230" y="0" width="110" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="285" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Cost Tracker</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(515, 465)">
|
||||||
|
<rect x="0" y="0" width="95" height="20" rx="3" fill="rgba(168,85,247,0.08)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="47" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Fallback Chain</text>
|
||||||
|
<rect x="105" y="0" width="90" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="150" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Cost Ranker</text>
|
||||||
|
<rect x="205" y="0" width="80" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="245" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Providers</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Routing indicator animation -->
|
||||||
|
<g transform="translate(855, 400)">
|
||||||
|
<line x1="-6" y1="0" x2="6" y2="0" stroke="#a855f7" stroke-width="1.5" opacity="0.5">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="4s" repeatCount="indefinite"/>
|
||||||
|
</line>
|
||||||
|
<line x1="0" y1="-6" x2="0" y2="6" stroke="#ec4899" stroke-width="1.5" opacity="0.5">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="4s" repeatCount="indefinite"/>
|
||||||
|
</line>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Swarm Coordinator -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="980" y="380" width="310" height="130" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="984" y="380" width="302" height="1.5" rx="1" fill="#ec4899" opacity="0.6"/>
|
||||||
|
<text x="1135" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#ec4899" text-anchor="middle" filter="url(#glow-sm)">Swarm Coordinator</text>
|
||||||
|
<text x="1135" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Load Balancing · Prometheus · 6 Tests</text>
|
||||||
|
|
||||||
|
<g transform="translate(995, 435)">
|
||||||
|
<rect x="0" y="0" width="90" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="45" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Assignment</text>
|
||||||
|
<rect x="100" y="0" width="90" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="145" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Filtering</text>
|
||||||
|
<rect x="200" y="0" width="80" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="240" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Metrics</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(995, 465)">
|
||||||
|
<rect x="0" y="0" width="130" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="65" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">success_rate / (1+load)</text>
|
||||||
|
<rect x="140" y="0" width="80" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="180" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Capabilities</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Swarm pulse -->
|
||||||
|
<circle cx="1270" cy="395" r="3" fill="#ec4899" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="2;5;2" dur="2s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.2;0.5;0.2" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- RLM → LLM Router connection -->
|
||||||
|
<path id="path-rlm-llm" d="M 400 445 L 500 445" fill="none" stroke="url(#grad-cyan-purple)" stroke-width="3" stroke-opacity="0.3"/>
|
||||||
|
<use href="#particle-cyan" opacity="0.7"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 400 445 L 500 445"/></use>
|
||||||
|
|
||||||
|
<!-- LLM Router → Swarm connection -->
|
||||||
|
<path d="M 880 445 L 980 445" fill="none" stroke="url(#grad-purple-pink)" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.6"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 880 445 L 980 445"/></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Intelligence → Data -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- RLM → KG -->
|
||||||
|
<path id="path-rlm-kg" d="M 160 510 L 160 575" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 160 510 L 160 575"/></use>
|
||||||
|
|
||||||
|
<!-- RLM → SurrealDB -->
|
||||||
|
<path id="path-rlm-sdb" d="M 300 510 L 300 540 Q 300 555 400 555 L 530 555 Q 545 555 545 575" fill="none" stroke="#22d3ee" stroke-width="2.4" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-cyan" opacity="0.7"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-rlm-sdb"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- LLM Router → Providers (goes down below data) -->
|
||||||
|
<path id="path-llm-providers" d="M 790 510 L 790 725" fill="none" stroke="#a855f7" stroke-width="3" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-purple" opacity="0.8"><animateMotion dur="3s" repeatCount="indefinite" path="M 790 510 L 790 725"/></use>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.5"><animateMotion dur="3s" begin="1.5s" repeatCount="indefinite" path="M 790 510 L 790 725"/></use>
|
||||||
|
|
||||||
|
<!-- Swarm → NATS -->
|
||||||
|
<path id="path-sw-nats" d="M 1135 510 L 1135 575" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 1135 510 L 1135 575"/></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 4: DATA LAYER (y=575) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Knowledge Graph -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="60" y="575" width="260" height="100" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="2"/>
|
||||||
|
<rect x="60" y="575" width="260" height="1.5" rx="1" fill="#22d3ee" opacity="0.5"/>
|
||||||
|
<text x="190" y="600" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Knowledge Graph</text>
|
||||||
|
<text x="190" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.4" text-anchor="middle">Temporal History · Learning Curves · 20 Tests</text>
|
||||||
|
<g transform="translate(75, 630)">
|
||||||
|
<rect x="0" y="0" width="80" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="40" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Executions</text>
|
||||||
|
<rect x="90" y="0" width="70" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="125" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Similarity</text>
|
||||||
|
<rect x="170" y="0" width="60" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="200" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Causal</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SurrealDB -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="420" y="575" width="340" height="100" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="420" y="575" width="340" height="2" rx="1" fill="url(#grad-main)" opacity="0.6"/>
|
||||||
|
<text x="590" y="600" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="url(#grad-main)" text-anchor="middle" filter="url(#glow-sm)">SurrealDB</text>
|
||||||
|
<text x="590" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Multi-Model Database · Multi-Tenant Scopes</text>
|
||||||
|
|
||||||
|
<g transform="translate(435, 630)">
|
||||||
|
<rect x="0" y="0" width="65" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="32" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Projects</text>
|
||||||
|
<rect x="75" y="0" width="50" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="100" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Tasks</text>
|
||||||
|
<rect x="135" y="0" width="55" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="162" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Agents</text>
|
||||||
|
<rect x="200" y="0" width="55" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="227" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Chunks</text>
|
||||||
|
<rect x="265" y="0" width="45" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="287" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">A2A</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- DB activity indicator -->
|
||||||
|
<g transform="translate(735, 590)">
|
||||||
|
<rect x="0" y="0" width="2" height="10" fill="#22d3ee" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="6;12;6" dur="1.2s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="5" y="0" width="2" height="8" fill="#a855f7" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="8;14;8" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="10" y="0" width="2" height="12" fill="#ec4899" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="10;16;10" dur="1s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- KG → SurrealDB -->
|
||||||
|
<line x1="320" y1="630" x2="420" y2="630" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 320 630 L 420 630"/></use>
|
||||||
|
|
||||||
|
<!-- NATS JetStream -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="860" y="575" width="340" height="100" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="860" y="575" width="340" height="1.5" rx="1" fill="#ec4899" opacity="0.5"/>
|
||||||
|
<text x="1030" y="600" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#ec4899" text-anchor="middle" filter="url(#glow-sm)">NATS JetStream</text>
|
||||||
|
<text x="1030" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Message Queue · Async Coordination · Pub/Sub</text>
|
||||||
|
|
||||||
|
<g transform="translate(875, 630)">
|
||||||
|
<rect x="0" y="0" width="75" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="37" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Agent Jobs</text>
|
||||||
|
<rect x="85" y="0" width="75" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="122" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Workflows</text>
|
||||||
|
<rect x="170" y="0" width="70" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="205" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Proposals</text>
|
||||||
|
<rect x="250" y="0" width="60" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="280" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">A2A</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Message pulse animation -->
|
||||||
|
<g transform="translate(1125, 590)">
|
||||||
|
<circle r="4" fill="none" stroke="#ffffff" stroke-width="2" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="3;8;3" dur="2s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="1;0.5;1" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle r="3" fill="#ffffff" opacity="0.07">
|
||||||
|
<animate attributeName="opacity" values="0.8;1;0.8" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SurrealDB ↔ NATS bridge line -->
|
||||||
|
<line x1="760" y1="625" x2="860" y2="625" stroke="url(#grad-purple-pink)" stroke-width="0.8" stroke-opacity="0.4" stroke-dasharray="4 3"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Data → Providers -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Central provider trunk (from LLM Router, already drawn) -->
|
||||||
|
<!-- Branch to each provider -->
|
||||||
|
<path id="path-to-claude" d="M 790 725 Q 790 750 500 750 L 245 750 Q 225 750 225 785" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-to-claude"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-openai" d="M 790 725 Q 790 760 600 760 L 555 760 Q 545 760 545 785" fill="none" stroke="#a855f7" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.6"><animateMotion dur="2s" repeatCount="indefinite"><mpath href="#path-to-openai"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-gemini" d="M 790 725 Q 790 770 810 770 L 855 770 Q 865 770 865 785" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.6"><animateMotion dur="2.2s" repeatCount="indefinite"><mpath href="#path-to-gemini"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-ollama" d="M 790 725 Q 790 750 900 750 L 1155 750 Q 1175 750 1175 785" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="2.8s" repeatCount="indefinite"><mpath href="#path-to-ollama"/></animateMotion></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 5: LLM PROVIDERS (y=810) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Claude -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="100" y="785" width="250" height="55" rx="6" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="225" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Anthropic Claude</text>
|
||||||
|
<text x="225" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.4" text-anchor="middle">Opus · Sonnet · Haiku</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- OpenAI -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="420" y="785" width="250" height="55" rx="6" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="545" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#a855f7" text-anchor="middle">OpenAI</text>
|
||||||
|
<text x="545" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.4" text-anchor="middle">GPT-4 · GPT-4o · GPT-3.5</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Gemini -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="740" y="785" width="250" height="55" rx="6" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="865" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#ec4899" text-anchor="middle">Google Gemini</text>
|
||||||
|
<text x="865" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.4" text-anchor="middle">2.0 Pro · Flash · 1.5 Pro</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Ollama -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="1060" y="785" width="250" height="55" rx="6" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="1185" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Ollama (Local)</text>
|
||||||
|
<text x="1185" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.4" text-anchor="middle">Llama · Mistral · CodeLlama</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- SUPPORTING CRATES (bottom strip) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<g transform="translate(0, 882)">
|
||||||
|
<rect x="60" y="0" width="1280" height="50" rx="6" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="700" y="16" font-family="'JetBrains Mono', monospace" font-size="9" fill="#a855f7" opacity="0.7" text-anchor="middle" letter-spacing="2">SUPPORTING CRATES</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="10" opacity="0.6" text-anchor="middle">
|
||||||
|
<text x="130" y="36" fill="#22d3ee">vapora-shared</text>
|
||||||
|
<text x="260" y="36" fill="#a855f7">vapora-tracking</text>
|
||||||
|
<text x="400" y="36" fill="#ec4899">vapora-telemetry</text>
|
||||||
|
<text x="540" y="36" fill="#22d3ee">vapora-analytics</text>
|
||||||
|
<text x="680" y="36" fill="#a855f7">vapora-worktree</text>
|
||||||
|
<text x="820" y="36" fill="#ec4899">vapora-doc-lifecycle</text>
|
||||||
|
<text x="975" y="36" fill="#22d3ee">vapora-workflow-engine</text>
|
||||||
|
<text x="1140" y="36" fill="#a855f7">vapora-cli</text>
|
||||||
|
<text x="1250" y="36" fill="#ec4899">vapora-leptos-ui</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- OBSERVABILITY STRIP (right edge) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<g transform="translate(1340, 80)">
|
||||||
|
<rect x="0" y="0" width="4" height="790" rx="2" fill="url(#grad-vertical)" opacity="0.3">
|
||||||
|
<animate attributeName="opacity" values="0.2;0.4;0.2" dur="5s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<text x="15" y="400" font-family="'JetBrains Mono', monospace" font-size="9" fill="#a855f7" opacity="0.6" letter-spacing="2" text-anchor="middle" transform="rotate(90 15 400)">PROMETHEUS · GRAFANA · OPENTELEMETRY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- FOOTER -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<text x="700" y="970" font-family="'JetBrains Mono', monospace" font-size="11" font-weight="700" fill="url(#grad-main)" text-anchor="middle" opacity="0.7" letter-spacing="3">VAPORA v1.2.0</text>
|
||||||
|
<text x="700" y="993" font-family="'Inter', sans-serif" font-size="9" fill="#a855f7" opacity="0.6" text-anchor="middle" letter-spacing="1">Evaporate complexity · Full-Stack Rust · Production Ready</text>
|
||||||
|
|
||||||
|
<!-- Bottom gradient bar -->
|
||||||
|
<rect x="400" y="1005" width="600" height="2" rx="1" fill="url(#grad-main)" opacity="0.3"/>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 42 KiB |
576
assets/web/src/vapora_architecture_white.svg
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 1020" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700;800&family=Inter:wght@400;500;600&display=swap');
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Brand gradients -->
|
||||||
|
<linearGradient id="grad-main" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee"/>
|
||||||
|
<stop offset="50%" stop-color="#a855f7"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-cyan-purple" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee"/>
|
||||||
|
<stop offset="100%" stop-color="#a855f7"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-purple-pink" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#a855f7"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-vertical" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.8"/>
|
||||||
|
<stop offset="50%" stop-color="#a855f7" stop-opacity="0.5"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899" stop-opacity="0.3"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-cyan" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.12"/>
|
||||||
|
<stop offset="100%" stop-color="#22d3ee" stop-opacity="0.03"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-purple" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#a855f7" stop-opacity="0.12"/>
|
||||||
|
<stop offset="100%" stop-color="#a855f7" stop-opacity="0.03"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-pink" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#ec4899" stop-opacity="0.12"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899" stop-opacity="0.03"/>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Glow filters -->
|
||||||
|
<filter id="glow-sm">
|
||||||
|
<feGaussianBlur stdDeviation="0.5" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glow-md">
|
||||||
|
<feGaussianBlur stdDeviation="4" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glow-lg">
|
||||||
|
<feGaussianBlur stdDeviation="6" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glass-card">
|
||||||
|
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"/>
|
||||||
|
<feOffset dx="0" dy="1" result="shadow"/>
|
||||||
|
<feFlood flood-color="#000" flood-opacity="0.3" result="color"/>
|
||||||
|
<feComposite in="color" in2="shadow" operator="in" result="shadow"/>
|
||||||
|
<feMerge><feMergeNode in="shadow"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Animated particle marker -->
|
||||||
|
<circle id="particle-cyan" r="3" fill="#22d3ee" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-purple" r="3" fill="#a855f7" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-pink" r="3" fill="#ec4899" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-sm-cyan" r="2" fill="#22d3ee" filter="url(#glow-sm)"/>
|
||||||
|
<circle id="particle-sm-purple" r="2" fill="#a855f7" filter="url(#glow-sm)"/>
|
||||||
|
<circle id="particle-sm-pink" r="2" fill="#ec4899" filter="url(#glow-sm)"/>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- BACKGROUND -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<rect width="1400" height="1020" fill="#ffffff"/>
|
||||||
|
|
||||||
|
<!-- Subtle tech grid -->
|
||||||
|
<g opacity="0.08" stroke="#22d3ee" stroke-width="0.5">
|
||||||
|
<line x1="0" y1="0" x2="1400" y2="0"><animate attributeName="y1" values="0;1020" dur="60s" repeatCount="indefinite"/><animate attributeName="y2" values="0;1020" dur="60s" repeatCount="indefinite"/></line>
|
||||||
|
<line x1="100" y1="0" x2="100" y2="1020"/>
|
||||||
|
<line x1="250" y1="0" x2="250" y2="1020"/>
|
||||||
|
<line x1="400" y1="0" x2="400" y2="1020"/>
|
||||||
|
<line x1="550" y1="0" x2="550" y2="1020"/>
|
||||||
|
<line x1="700" y1="0" x2="700" y2="1020"/>
|
||||||
|
<line x1="850" y1="0" x2="850" y2="1020"/>
|
||||||
|
<line x1="1000" y1="0" x2="1000" y2="1020"/>
|
||||||
|
<line x1="1150" y1="0" x2="1150" y2="1020"/>
|
||||||
|
<line x1="1300" y1="0" x2="1300" y2="1020"/>
|
||||||
|
<line x1="0" y1="130" x2="1400" y2="130"/>
|
||||||
|
<line x1="0" y1="260" x2="1400" y2="260"/>
|
||||||
|
<line x1="0" y1="420" x2="1400" y2="420"/>
|
||||||
|
<line x1="0" y1="580" x2="1400" y2="580"/>
|
||||||
|
<line x1="0" y1="720" x2="1400" y2="720"/>
|
||||||
|
<line x1="0" y1="860" x2="1400" y2="860"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Ambient glow orbs -->
|
||||||
|
<circle cx="240" cy="350" r="180" fill="#22d3ee" opacity="0.05">
|
||||||
|
<animate attributeName="r" values="160;200;160" dur="8s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="690" cy="360" r="175" fill="#a855f7" opacity="0.04">
|
||||||
|
<animate attributeName="r" values="175;195;175" dur="10s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="1130" cy="350" r="200" fill="#ec4899" opacity="0.05">
|
||||||
|
<animate attributeName="r" values="180;220;180" dur="9s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- TITLE -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<text x="700" y="42" font-family="'JetBrains Mono', monospace" font-size="22" font-weight="800" fill="url(#grad-main)" letter-spacing="6" text-anchor="middle" filter="url(#glow-sm)">VAPORA ARCHITECTURE</text>
|
||||||
|
<text x="700" y="62" font-family="'Inter', sans-serif" font-size="11" fill="#a855f7" opacity="0.6" letter-spacing="3" text-anchor="middle">18 CRATES · 354 TESTS · 100% RUST</text>
|
||||||
|
|
||||||
|
<!-- Layer labels (left side) -->
|
||||||
|
<text x="30" y="115" font-family="'JetBrains Mono', monospace" font-size="10" fill="#22d3ee" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 115)">PRESENTATION</text>
|
||||||
|
<text x="30" y="290" font-family="'JetBrains Mono', monospace" font-size="10" fill="#a855f7" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 290)">SERVICES</text>
|
||||||
|
<text x="30" y="485" font-family="'JetBrains Mono', monospace" font-size="10" fill="#ec4899" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 485)">INTELLIGENCE</text>
|
||||||
|
<text x="30" y="640" font-family="'JetBrains Mono', monospace" font-size="10" fill="#22d3ee" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 640)">DATA</text>
|
||||||
|
<text x="30" y="850" font-family="'JetBrains Mono', monospace" font-size="10" fill="#a855f7" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 850)">PROVIDERS</text>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 1: FRONTEND (y=80) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Frontend card -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="490" y="80" width="420" height="65" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.4" stroke-width="1"/>
|
||||||
|
<rect x="494" y="80" width="412" height="1.5" rx="1" fill="url(#grad-main)" opacity="0.8"/>
|
||||||
|
<text x="700" y="106" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#22d3ee" text-anchor="middle" filter="url(#glow-sm)">Leptos WASM Frontend</text>
|
||||||
|
<text x="700" y="124" font-family="'Inter', sans-serif" font-size="10" fill="#1f2937" opacity="0.85" text-anchor="middle">Kanban Board · Glassmorphism UI · UnoCSS · Reactive Components</text>
|
||||||
|
<!-- Pulse ring -->
|
||||||
|
<rect x="490" y="80" width="420" height="65" rx="8" fill="none" stroke="#22d3ee" stroke-opacity="0.15">
|
||||||
|
<animate attributeName="stroke-opacity" values="0.15;0.3;0.15" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTION: Frontend → Services -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Frontend to Backend -->
|
||||||
|
<path id="path-fe-be" d="M 580 145 L 580 160 Q 580 175 480 175 L 280 175 Q 260 175 260 195 L 260 210" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.8"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-fe-be"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- Frontend to Agents -->
|
||||||
|
<line x1="700" y1="145" x2="700" y2="210" stroke="#a855f7" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.8"><animateMotion dur="2s" repeatCount="indefinite" path="M 700 145 L 700 210"/></use>
|
||||||
|
|
||||||
|
<!-- Frontend to MCP -->
|
||||||
|
<path id="path-fe-mcp" d="M 820 145 L 820 160 Q 820 175 920 175 L 1100 175 Q 1140 175 1140 195 L 1140 210" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.8"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-fe-mcp"/></animateMotion></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 2: SERVICES (y=210) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Backend / Axum API -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="100" y="210" width="310" height="100" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="104" y="210" width="302" height="1.5" rx="1" fill="#22d3ee" opacity="0.6"/>
|
||||||
|
<text x="255" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#22d3ee" text-anchor="middle">Axum Backend API</text>
|
||||||
|
<text x="255" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">40+ REST Endpoints · 161 Tests</text>
|
||||||
|
<!-- Sub-items -->
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.65">
|
||||||
|
<text x="120" y="278">Projects</text>
|
||||||
|
<text x="180" y="278">Tasks</text>
|
||||||
|
<text x="225" y="278">Agents</text>
|
||||||
|
<text x="280" y="278">Workflows</text>
|
||||||
|
<text x="350" y="278">Proposals</text>
|
||||||
|
<text x="120" y="294">Swarm</text>
|
||||||
|
<text x="175" y="294">Metrics</text>
|
||||||
|
<text x="235" y="294">RLM API</text>
|
||||||
|
<text x="300" y="294">WebSocket</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Agent Runtime -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="540" y="210" width="310" height="100" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="544" y="210" width="302" height="1.5" rx="1" fill="#a855f7" opacity="0.6"/>
|
||||||
|
<text x="695" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#a855f7" text-anchor="middle">Agent Runtime</text>
|
||||||
|
<text x="695" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Orchestration · Learning Profiles · 71 Tests</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.65">
|
||||||
|
<text x="560" y="278">Registry</text>
|
||||||
|
<text x="625" y="278">Coordinator</text>
|
||||||
|
<text x="720" y="278">Scoring</text>
|
||||||
|
<text x="785" y="278">Profiles</text>
|
||||||
|
<text x="560" y="294">12 Roles</text>
|
||||||
|
<text x="630" y="294">Health Checks</text>
|
||||||
|
<text x="735" y="294">Recency Bias</text>
|
||||||
|
</g>
|
||||||
|
<!-- Heartbeat animation -->
|
||||||
|
<circle cx="835" cy="225" r="4" fill="#a855f7" opacity="0.04">
|
||||||
|
<animate attributeName="r" values="3;5;3" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.3;0.6;0.3" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- MCP Gateway -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="980" y="210" width="310" height="100" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="984" y="210" width="302" height="1.5" rx="1" fill="#ec4899" opacity="0.6"/>
|
||||||
|
<text x="1135" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#ec4899" text-anchor="middle">MCP Gateway</text>
|
||||||
|
<text x="1135" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Model Context Protocol · Plugin System</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.65">
|
||||||
|
<text x="1000" y="278">Stdio Transport</text>
|
||||||
|
<text x="1105" y="278">SSE Transport</text>
|
||||||
|
<text x="1210" y="278">JSON-RPC</text>
|
||||||
|
<text x="1000" y="294">6 Tools</text>
|
||||||
|
<text x="1060" y="294">Tool Registry</text>
|
||||||
|
<text x="1160" y="294">Schema Validation</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- A2A Protocol (small card overlapping) -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="445" y="280" width="86" height="35" rx="6" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="488" y="300" font-family="'JetBrains Mono', monospace" font-size="9" font-weight="700" fill="#a855f7" opacity="0.6" text-anchor="middle">A2A Protocol</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Services → Intelligence -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Backend → RLM -->
|
||||||
|
<path id="path-be-rlm" d="M 200 310 L 200 380" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 200 310 L 200 380"/></use>
|
||||||
|
|
||||||
|
<!-- Backend → SurrealDB (arco por la derecha para evitar KG) -->
|
||||||
|
<path id="path-be-sdb" d="M 320 310 L 320 340 Q 320 360 360 360 L 420 360 Q 435 360 435 380 Q 435 580 420 580 L 420 585" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.35" stroke-dasharray="4 4"/>
|
||||||
|
|
||||||
|
<!-- Agents → LLM Router -->
|
||||||
|
<line x1="695" y1="310" x2="695" y2="380" stroke="#a855f7" stroke-width="2.4" stroke-opacity="0.3"/>
|
||||||
|
<use href="#particle-purple" opacity="0.8"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 695 310 L 695 380"/></use>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.5"><animateMotion dur="1.5s" begin="0.75s" repeatCount="indefinite" path="M 695 310 L 695 380"/></use>
|
||||||
|
|
||||||
|
<!-- Agents → Swarm -->
|
||||||
|
<path id="path-ag-sw" d="M 800 310 L 800 340 Q 800 355 900 355 L 1050 355 Q 1070 355 1070 375 L 1070 380" fill="none" stroke="#a855f7" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.6"><animateMotion dur="2.2s" repeatCount="indefinite"><mpath href="#path-ag-sw"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- MCP → Agents -->
|
||||||
|
<path id="path-mcp-ag" d="M 1020 310 L 1020 320 Q 1020 332 920 332 L 810 332 Q 800 332 800 320 L 800 310" fill="none" stroke="#ec4899" stroke-width="1.6" stroke-opacity="0.35" stroke-dasharray="3 3"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 3: INTELLIGENCE (y=380) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- RLM Engine -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="60" y="380" width="340" height="130" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="64" y="380" width="332" height="2" rx="1" fill="url(#grad-main)" opacity="0.7"/>
|
||||||
|
<text x="230" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="url(#grad-main)" text-anchor="middle" filter="url(#glow-sm)">RLM Engine</text>
|
||||||
|
<text x="230" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Recursive Language Models · 38 Tests · 17k+ LOC</text>
|
||||||
|
|
||||||
|
<!-- RLM sub-components as mini pills -->
|
||||||
|
<g transform="translate(75, 435)">
|
||||||
|
<!-- Chunking -->
|
||||||
|
<rect x="0" y="0" width="80" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="40" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Chunking</text>
|
||||||
|
<!-- Hybrid Search -->
|
||||||
|
<rect x="90" y="0" width="95" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="137" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Hybrid Search</text>
|
||||||
|
<!-- Dispatcher -->
|
||||||
|
<rect x="195" y="0" width="80" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="235" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Dispatcher</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(75, 465)">
|
||||||
|
<!-- BM25 -->
|
||||||
|
<rect x="0" y="0" width="65" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="32" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">BM25</text>
|
||||||
|
<!-- Semantic -->
|
||||||
|
<rect x="75" y="0" width="70" height="20" rx="3" fill="rgba(168,85,247,0.08)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="110" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Semantic</text>
|
||||||
|
<!-- RRF -->
|
||||||
|
<rect x="155" y="0" width="50" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="180" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">RRF</text>
|
||||||
|
<!-- Sandbox -->
|
||||||
|
<rect x="215" y="0" width="60" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="245" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Sandbox</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Animated search indicator -->
|
||||||
|
<g transform="translate(370, 400)">
|
||||||
|
<circle r="6" fill="none" stroke="#22d3ee" stroke-width="0.8" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="4;8;4" dur="3s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.4;0.1;0.4" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle r="3" fill="#22d3ee" opacity="0.07">
|
||||||
|
<animate attributeName="opacity" values="0.2;0.5;0.2" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- LLM Router -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="500" y="380" width="380" height="130" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="504" y="380" width="372" height="2" rx="1" fill="#a855f7" opacity="0.7"/>
|
||||||
|
<text x="690" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#a855f7" text-anchor="middle" filter="url(#glow-sm)">Multi-IA LLM Router</text>
|
||||||
|
<text x="690" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Budget Enforcement · Cost Tracking · 53 Tests</text>
|
||||||
|
|
||||||
|
<!-- Router sub-components -->
|
||||||
|
<g transform="translate(515, 435)">
|
||||||
|
<rect x="0" y="0" width="95" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="47" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Rule Router</text>
|
||||||
|
<rect x="105" y="0" width="115" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="162" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Budget Manager</text>
|
||||||
|
<rect x="230" y="0" width="110" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="285" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Cost Tracker</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(515, 465)">
|
||||||
|
<rect x="0" y="0" width="95" height="20" rx="3" fill="rgba(168,85,247,0.08)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="47" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Fallback Chain</text>
|
||||||
|
<rect x="105" y="0" width="90" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="150" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Cost Ranker</text>
|
||||||
|
<rect x="205" y="0" width="80" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="245" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Providers</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Routing indicator animation -->
|
||||||
|
<g transform="translate(855, 400)">
|
||||||
|
<line x1="-6" y1="0" x2="6" y2="0" stroke="#a855f7" stroke-width="1.5" opacity="0.5">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="4s" repeatCount="indefinite"/>
|
||||||
|
</line>
|
||||||
|
<line x1="0" y1="-6" x2="0" y2="6" stroke="#ec4899" stroke-width="1.5" opacity="0.5">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="4s" repeatCount="indefinite"/>
|
||||||
|
</line>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Swarm Coordinator -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="980" y="380" width="310" height="130" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="984" y="380" width="302" height="1.5" rx="1" fill="#ec4899" opacity="0.6"/>
|
||||||
|
<text x="1135" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#ec4899" text-anchor="middle" filter="url(#glow-sm)">Swarm Coordinator</text>
|
||||||
|
<text x="1135" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Load Balancing · Prometheus · 6 Tests</text>
|
||||||
|
|
||||||
|
<g transform="translate(995, 435)">
|
||||||
|
<rect x="0" y="0" width="90" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="45" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Assignment</text>
|
||||||
|
<rect x="100" y="0" width="90" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="145" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Filtering</text>
|
||||||
|
<rect x="200" y="0" width="80" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="240" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Metrics</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(995, 465)">
|
||||||
|
<rect x="0" y="0" width="130" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="65" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">success_rate / (1+load)</text>
|
||||||
|
<rect x="140" y="0" width="80" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="180" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Capabilities</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Swarm pulse -->
|
||||||
|
<circle cx="1270" cy="395" r="3" fill="#ec4899" opacity="0.04">
|
||||||
|
<animate attributeName="r" values="2;5;2" dur="2s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.2;0.5;0.2" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- RLM → LLM Router connection -->
|
||||||
|
<path id="path-rlm-llm" d="M 400 445 L 500 445" fill="none" stroke="url(#grad-cyan-purple)" stroke-width="3" stroke-opacity="0.3"/>
|
||||||
|
<use href="#particle-cyan" opacity="0.7"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 400 445 L 500 445"/></use>
|
||||||
|
|
||||||
|
<!-- LLM Router → Swarm connection -->
|
||||||
|
<path d="M 880 445 L 980 445" fill="none" stroke="url(#grad-purple-pink)" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.6"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 880 445 L 980 445"/></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Intelligence → Data -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- RLM → KG -->
|
||||||
|
<path id="path-rlm-kg" d="M 160 510 L 160 575" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 160 510 L 160 575"/></use>
|
||||||
|
|
||||||
|
<!-- RLM → SurrealDB -->
|
||||||
|
<path id="path-rlm-sdb" d="M 300 510 L 300 540 Q 300 555 400 555 L 530 555 Q 545 555 545 575" fill="none" stroke="#22d3ee" stroke-width="2.4" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-cyan" opacity="0.7"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-rlm-sdb"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- LLM Router → Providers (goes down below data) -->
|
||||||
|
<path id="path-llm-providers" d="M 790 510 L 790 725" fill="none" stroke="#a855f7" stroke-width="3" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-purple" opacity="0.8"><animateMotion dur="3s" repeatCount="indefinite" path="M 790 510 L 790 725"/></use>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.5"><animateMotion dur="3s" begin="1.5s" repeatCount="indefinite" path="M 790 510 L 790 725"/></use>
|
||||||
|
|
||||||
|
<!-- Swarm → NATS -->
|
||||||
|
<path id="path-sw-nats" d="M 1135 510 L 1135 575" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 1135 510 L 1135 575"/></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 4: DATA LAYER (y=575) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Knowledge Graph -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="60" y="575" width="260" height="100" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="1"/>
|
||||||
|
<rect x="60" y="575" width="260" height="1.5" rx="1" fill="#22d3ee" opacity="0.5"/>
|
||||||
|
<text x="190" y="600" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Knowledge Graph</text>
|
||||||
|
<text x="190" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.7" text-anchor="middle">Temporal History · Learning Curves · 20 Tests</text>
|
||||||
|
<g transform="translate(75, 630)">
|
||||||
|
<rect x="0" y="0" width="80" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="40" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Executions</text>
|
||||||
|
<rect x="90" y="0" width="70" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="125" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Similarity</text>
|
||||||
|
<rect x="170" y="0" width="60" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="200" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Causal</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SurrealDB -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="420" y="575" width="340" height="100" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="420" y="575" width="340" height="2" rx="1" fill="url(#grad-main)" opacity="0.6"/>
|
||||||
|
<text x="590" y="600" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="url(#grad-main)" text-anchor="middle" filter="url(#glow-sm)">SurrealDB</text>
|
||||||
|
<text x="590" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Multi-Model Database · Multi-Tenant Scopes</text>
|
||||||
|
|
||||||
|
<g transform="translate(435, 630)">
|
||||||
|
<rect x="0" y="0" width="65" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="32" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Projects</text>
|
||||||
|
<rect x="75" y="0" width="50" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="100" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Tasks</text>
|
||||||
|
<rect x="135" y="0" width="55" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="162" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Agents</text>
|
||||||
|
<rect x="200" y="0" width="55" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="227" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Chunks</text>
|
||||||
|
<rect x="265" y="0" width="45" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="287" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">A2A</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- DB activity indicator -->
|
||||||
|
<g transform="translate(735, 590)">
|
||||||
|
<rect x="0" y="0" width="2" height="10" fill="#22d3ee" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="6;12;6" dur="1.2s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="5" y="0" width="2" height="8" fill="#a855f7" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="8;14;8" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="10" y="0" width="2" height="12" fill="#ec4899" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="10;16;10" dur="1s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- KG → SurrealDB -->
|
||||||
|
<line x1="320" y1="630" x2="420" y2="630" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 320 630 L 420 630"/></use>
|
||||||
|
|
||||||
|
<!-- NATS JetStream -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="860" y="575" width="340" height="100" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="860" y="575" width="340" height="1.5" rx="1" fill="#ec4899" opacity="0.5"/>
|
||||||
|
<text x="1030" y="600" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#ec4899" text-anchor="middle" filter="url(#glow-sm)">NATS JetStream</text>
|
||||||
|
<text x="1030" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Message Queue · Async Coordination · Pub/Sub</text>
|
||||||
|
|
||||||
|
<g transform="translate(875, 630)">
|
||||||
|
<rect x="0" y="0" width="75" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="37" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Agent Jobs</text>
|
||||||
|
<rect x="85" y="0" width="75" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="122" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Workflows</text>
|
||||||
|
<rect x="170" y="0" width="70" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="205" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Proposals</text>
|
||||||
|
<rect x="250" y="0" width="60" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="280" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">A2A</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Message pulse animation -->
|
||||||
|
<g transform="translate(1125, 590)">
|
||||||
|
<circle r="4" fill="none" stroke="#22d3ee" stroke-width="1.5" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="3;8;3" dur="2s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="1;0.4;1" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle r="2" fill="#22d3ee" opacity="0.07">
|
||||||
|
<animate attributeName="opacity" values="0.7;1;0.7" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SurrealDB ↔ NATS bridge line -->
|
||||||
|
<line x1="760" y1="625" x2="860" y2="625" stroke="url(#grad-purple-pink)" stroke-width="0.8" stroke-opacity="0.4" stroke-dasharray="4 3"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Data → Providers -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Central provider trunk (from LLM Router, already drawn) -->
|
||||||
|
<!-- Branch to each provider -->
|
||||||
|
<path id="path-to-claude" d="M 790 725 Q 790 750 500 750 L 245 750 Q 225 750 225 785" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-to-claude"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-openai" d="M 790 725 Q 790 760 600 760 L 555 760 Q 545 760 545 785" fill="none" stroke="#a855f7" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.6"><animateMotion dur="2s" repeatCount="indefinite"><mpath href="#path-to-openai"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-gemini" d="M 790 725 Q 790 770 810 770 L 855 770 Q 865 770 865 785" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.6"><animateMotion dur="2.2s" repeatCount="indefinite"><mpath href="#path-to-gemini"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-ollama" d="M 790 725 Q 790 750 900 750 L 1155 750 Q 1175 750 1175 785" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="2.8s" repeatCount="indefinite"><mpath href="#path-to-ollama"/></animateMotion></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 5: LLM PROVIDERS (y=810) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Claude -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="100" y="785" width="250" height="55" rx="6" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="225" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Anthropic Claude</text>
|
||||||
|
<text x="225" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.7" text-anchor="middle">Opus · Sonnet · Haiku</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- OpenAI -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="420" y="785" width="250" height="55" rx="6" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="545" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#a855f7" text-anchor="middle">OpenAI</text>
|
||||||
|
<text x="545" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.7" text-anchor="middle">GPT-4 · GPT-4o · GPT-3.5</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Gemini -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="740" y="785" width="250" height="55" rx="6" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="865" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#ec4899" text-anchor="middle">Google Gemini</text>
|
||||||
|
<text x="865" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.7" text-anchor="middle">2.0 Pro · Flash · 1.5 Pro</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Ollama -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="1060" y="785" width="250" height="55" rx="6" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="1185" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Ollama (Local)</text>
|
||||||
|
<text x="1185" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.7" text-anchor="middle">Llama · Mistral · CodeLlama</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- SUPPORTING CRATES (bottom strip) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<g transform="translate(0, 882)">
|
||||||
|
<rect x="60" y="0" width="1280" height="50" rx="6" fill="rgba(168,85,247,0.04)" stroke="#a855f7" stroke-opacity="0.1" stroke-width="0.5"/>
|
||||||
|
<text x="700" y="16" font-family="'JetBrains Mono', monospace" font-size="9" fill="#a855f7" opacity="0.7" text-anchor="middle" letter-spacing="2">SUPPORTING CRATES</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="10" opacity="0.6" text-anchor="middle">
|
||||||
|
<text x="130" y="36" fill="#22d3ee">vapora-shared</text>
|
||||||
|
<text x="260" y="36" fill="#a855f7">vapora-tracking</text>
|
||||||
|
<text x="400" y="36" fill="#ec4899">vapora-telemetry</text>
|
||||||
|
<text x="540" y="36" fill="#22d3ee">vapora-analytics</text>
|
||||||
|
<text x="680" y="36" fill="#a855f7">vapora-worktree</text>
|
||||||
|
<text x="820" y="36" fill="#ec4899">vapora-doc-lifecycle</text>
|
||||||
|
<text x="975" y="36" fill="#22d3ee">vapora-workflow-engine</text>
|
||||||
|
<text x="1140" y="36" fill="#a855f7">vapora-cli</text>
|
||||||
|
<text x="1250" y="36" fill="#ec4899">vapora-leptos-ui</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- OBSERVABILITY STRIP (right edge) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<g transform="translate(1340, 80)">
|
||||||
|
<rect x="0" y="0" width="4" height="790" rx="2" fill="url(#grad-vertical)" opacity="0.3">
|
||||||
|
<animate attributeName="opacity" values="0.2;0.4;0.2" dur="5s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<text x="15" y="400" font-family="'JetBrains Mono', monospace" font-size="9" fill="#a855f7" opacity="0.6" letter-spacing="2" text-anchor="middle" transform="rotate(90 15 400)">PROMETHEUS · GRAFANA · OPENTELEMETRY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- FOOTER -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<text x="700" y="970" font-family="'JetBrains Mono', monospace" font-size="11" font-weight="700" fill="url(#grad-main)" text-anchor="middle" opacity="0.7" letter-spacing="3">VAPORA v1.2.0</text>
|
||||||
|
<text x="700" y="993" font-family="'Inter', sans-serif" font-size="9" fill="#a855f7" opacity="0.6" text-anchor="middle" letter-spacing="1">Evaporate complexity · Full-Stack Rust · Production Ready</text>
|
||||||
|
|
||||||
|
<!-- Bottom gradient bar -->
|
||||||
|
<rect x="400" y="1005" width="600" height="2" rx="1" fill="url(#grad-main)" opacity="0.3"/>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 42 KiB |
119
assets/web/src/vapora_white.svg
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="170 40 590 300" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
|
||||||
|
<defs>
|
||||||
|
<!-- Google Fonts import -->
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@800&display=swap');
|
||||||
|
</style>
|
||||||
|
<linearGradient id="techGradWhite" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:#22d3ee;stop-opacity:1"/>
|
||||||
|
<stop offset="50%" style="stop-color:#a855f7;stop-opacity:1"/>
|
||||||
|
<stop offset="100%" style="stop-color:#ec4899;stop-opacity:1"/>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="vertGradWhite" x1="0%" y1="100%" x2="0%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:#22d3ee;stop-opacity:1"/>
|
||||||
|
<stop offset="50%" style="stop-color:#a855f7;stop-opacity:0.8"/>
|
||||||
|
<stop offset="100%" style="stop-color:#ec4899;stop-opacity:0.4"/>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<filter id="techGlowWhite">
|
||||||
|
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<filter id="strongGlowWhite">
|
||||||
|
<feGaussianBlur stdDeviation="4" result="coloredBlur"/>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<filter id="glassWhite">
|
||||||
|
<feGaussianBlur in="SourceGraphic" stdDeviation="0.5" result="blur"/>
|
||||||
|
<feColorMatrix in="blur" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" result="goo"/>
|
||||||
|
<feBlend in="SourceGraphic" in2="goo"/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Fondo blanco -->
|
||||||
|
<rect width="800" height="400" fill="#ffffff"/>
|
||||||
|
|
||||||
|
<!-- Grid de fondo técnico sutil -->
|
||||||
|
<g opacity="0.08" stroke="#22d3ee" stroke-width="1">
|
||||||
|
<line x1="0" y1="133" x2="800" y2="133"/>
|
||||||
|
<line x1="0" y1="200" x2="800" y2="200"/>
|
||||||
|
<line x1="0" y1="267" x2="800" y2="267"/>
|
||||||
|
<line x1="133" y1="0" x2="133" y2="400"/>
|
||||||
|
<line x1="267" y1="0" x2="267" y2="400"/>
|
||||||
|
<line x1="400" y1="0" x2="400" y2="400"/>
|
||||||
|
<line x1="533" y1="0" x2="533" y2="400"/>
|
||||||
|
<line x1="667" y1="0" x2="667" y2="400"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Símbolo técnico: flujo de datos ascendente -->
|
||||||
|
<g transform="translate(267, 280)">
|
||||||
|
<rect x="-25" y="0" width="50" height="6.67" fill="url(#techGradWhite)" opacity="0.8" rx="3.33"/>
|
||||||
|
|
||||||
|
<path d="M 0 0 L 0 -50 L 8.33 -58 L -8.33 -75 L 8.33 -92 L -8.33 -108 L 8.33 -125 L 0 -133 L 0 -200" stroke="url(#vertGradWhite)" stroke-width="5" fill="none" stroke-linecap="round" stroke-linejoin="round" filter="url(#techGlowWhite)"/>
|
||||||
|
|
||||||
|
<path d="M -33 0 L -33 -42 L -30 -58 L -37 -75 L -30 -92 L -37 -108 L -33 -125 L -33 -167" stroke="#22d3ee" stroke-width="3.33" fill="none" stroke-linecap="round" opacity="0.6" filter="url(#techGlowWhite)"/>
|
||||||
|
|
||||||
|
<path d="M -58 0 L -58 -33 L -53 -50 L -63 -67 L -53 -83 L -63 -100 L -58 -117 L -58 -142" stroke="#a855f7" stroke-width="2.5" fill="none" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
|
||||||
|
<path d="M 33 0 L 33 -42 L 30 -58 L 37 -75 L 30 -92 L 37 -108 L 33 -125 L 33 -167" stroke="#ec4899" stroke-width="3.33" fill="none" stroke-linecap="round" opacity="0.6" filter="url(#techGlowWhite)"/>
|
||||||
|
|
||||||
|
<path d="M 58 0 L 58 -33 L 53 -50 L 63 -67 L 53 -83 L 63 -100 L 58 -117 L 58 -142" stroke="#22d3ee" stroke-width="2.5" fill="none" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
|
||||||
|
<circle cx="0" cy="-67" r="5" fill="#22d3ee" filter="url(#strongGlowWhite)"/>
|
||||||
|
<circle cx="0" cy="-100" r="4.17" fill="#a855f7" filter="url(#strongGlowWhite)"/>
|
||||||
|
<circle cx="0" cy="-133" r="3.33" fill="#ec4899" filter="url(#strongGlowWhite)"/>
|
||||||
|
|
||||||
|
<circle cx="-33" cy="-83" r="3.33" fill="#22d3ee" opacity="0.7"/>
|
||||||
|
<circle cx="33" cy="-92" r="3.33" fill="#ec4899" opacity="0.7"/>
|
||||||
|
<circle cx="-58" cy="-58" r="2.5" fill="#a855f7" opacity="0.5"/>
|
||||||
|
<circle cx="58" cy="-67" r="2.5" fill="#22d3ee" opacity="0.5"/>
|
||||||
|
|
||||||
|
<polygon points="0,-158 5,-162 5,-167 0,-170 -5,-167 -5,-162" stroke="#22d3ee" fill="none" stroke-width="1.67" opacity="0.6"/>
|
||||||
|
<polygon points="-42,-117 -37,-120 -37,-125 -42,-128 -47,-125 -47,-120" stroke="#a855f7" fill="none" stroke-width="1.67" opacity="0.5"/>
|
||||||
|
<polygon points="42,-125 47,-128 47,-133 42,-137 37,-133 37,-128" stroke="#ec4899" fill="none" stroke-width="1.67" opacity="0.5"/>
|
||||||
|
|
||||||
|
<line x1="-33" y1="-100" x2="-8" y2="-100" stroke="#22d3ee" stroke-width="0.83" opacity="0.4"/>
|
||||||
|
<line x1="8" y1="-117" x2="33" y2="-117" stroke="#ec4899" stroke-width="0.83" opacity="0.4"/>
|
||||||
|
<line x1="-58" y1="-83" x2="-37" y2="-83" stroke="#a855f7" stroke-width="0.83" opacity="0.3"/>
|
||||||
|
<line x1="37" y1="-92" x2="58" y2="-92" stroke="#22d3ee" stroke-width="0.83" opacity="0.3"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Texto VAPORA -->
|
||||||
|
<g filter="url(#glassWhite)">
|
||||||
|
<text x="550" y="207" font-family="'JetBrains Mono', 'Fira Code', monospace" font-size="90" font-weight="800" fill="url(#techGradWhite)" letter-spacing="5" text-anchor="middle">
|
||||||
|
VAPORA
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<text x="550" y="207" font-family="'JetBrains Mono', 'Fira Code', monospace" font-size="90" font-weight="800" fill="none" stroke="rgba(0,0,0,0.1)" stroke-width="0.83" letter-spacing="5" text-anchor="middle">
|
||||||
|
VAPORA
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Glow en texto -->
|
||||||
|
<text x="550" y="207" font-family="'JetBrains Mono', 'Fira Code', monospace" font-size="90" font-weight="800" fill="url(#techGradWhite)" letter-spacing="5" filter="url(#techGlowWhite)" opacity="0.3" text-anchor="middle">
|
||||||
|
VAPORA
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<!-- Tagline -->
|
||||||
|
<text x="550" y="240" font-family="'Inter', sans-serif" font-size="20" fill="#a855f7" opacity="0.8" letter-spacing="0.25em" text-anchor="middle">
|
||||||
|
Evaporate complexity
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<!-- Indicador técnico decorativo -->
|
||||||
|
<g transform="translate(550, 280)">
|
||||||
|
<rect x="0" y="0" width="2" height="13.33" fill="#22d3ee" opacity="0.6"/>
|
||||||
|
<rect x="6.67" y="0" width="2" height="16.67" fill="#a855f7" opacity="0.6"/>
|
||||||
|
<rect x="13.33" y="0" width="2" height="10" fill="#ec4899" opacity="0.6"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.0 KiB |
576
assets/web/vapora_architecture.svg
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 1020" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700;800&family=Inter:wght@400;500;600&display=swap');
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Brand gradients -->
|
||||||
|
<linearGradient id="grad-main" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee"/>
|
||||||
|
<stop offset="50%" stop-color="#a855f7"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-cyan-purple" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee"/>
|
||||||
|
<stop offset="100%" stop-color="#a855f7"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-purple-pink" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#a855f7"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-vertical" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.8"/>
|
||||||
|
<stop offset="50%" stop-color="#a855f7" stop-opacity="0.5"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899" stop-opacity="0.3"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-cyan" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.15"/>
|
||||||
|
<stop offset="100%" stop-color="#22d3ee" stop-opacity="0.05"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-purple" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#a855f7" stop-opacity="0.15"/>
|
||||||
|
<stop offset="100%" stop-color="#a855f7" stop-opacity="0.05"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-pink" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#ec4899" stop-opacity="0.15"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899" stop-opacity="0.05"/>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Glow filters -->
|
||||||
|
<filter id="glow-sm">
|
||||||
|
<feGaussianBlur stdDeviation="2" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glow-md">
|
||||||
|
<feGaussianBlur stdDeviation="4" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glow-lg">
|
||||||
|
<feGaussianBlur stdDeviation="6" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glass-card">
|
||||||
|
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"/>
|
||||||
|
<feOffset dx="0" dy="1" result="shadow"/>
|
||||||
|
<feFlood flood-color="#000" flood-opacity="0.3" result="color"/>
|
||||||
|
<feComposite in="color" in2="shadow" operator="in" result="shadow"/>
|
||||||
|
<feMerge><feMergeNode in="shadow"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Animated particle marker -->
|
||||||
|
<circle id="particle-cyan" r="3" fill="#22d3ee" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-purple" r="3" fill="#a855f7" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-pink" r="3" fill="#ec4899" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-sm-cyan" r="2" fill="#22d3ee" filter="url(#glow-sm)"/>
|
||||||
|
<circle id="particle-sm-purple" r="2" fill="#a855f7" filter="url(#glow-sm)"/>
|
||||||
|
<circle id="particle-sm-pink" r="2" fill="#ec4899" filter="url(#glow-sm)"/>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- BACKGROUND -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<rect width="1400" height="1020" fill="#0a0a0a"/>
|
||||||
|
|
||||||
|
<!-- Subtle tech grid -->
|
||||||
|
<g opacity="0.04" stroke="#22d3ee" stroke-width="0.5">
|
||||||
|
<line x1="0" y1="0" x2="1400" y2="0"><animate attributeName="y1" values="0;1020" dur="60s" repeatCount="indefinite"/><animate attributeName="y2" values="0;1020" dur="60s" repeatCount="indefinite"/></line>
|
||||||
|
<line x1="100" y1="0" x2="100" y2="1020"/>
|
||||||
|
<line x1="250" y1="0" x2="250" y2="1020"/>
|
||||||
|
<line x1="400" y1="0" x2="400" y2="1020"/>
|
||||||
|
<line x1="550" y1="0" x2="550" y2="1020"/>
|
||||||
|
<line x1="700" y1="0" x2="700" y2="1020"/>
|
||||||
|
<line x1="850" y1="0" x2="850" y2="1020"/>
|
||||||
|
<line x1="1000" y1="0" x2="1000" y2="1020"/>
|
||||||
|
<line x1="1150" y1="0" x2="1150" y2="1020"/>
|
||||||
|
<line x1="1300" y1="0" x2="1300" y2="1020"/>
|
||||||
|
<line x1="0" y1="130" x2="1400" y2="130"/>
|
||||||
|
<line x1="0" y1="260" x2="1400" y2="260"/>
|
||||||
|
<line x1="0" y1="420" x2="1400" y2="420"/>
|
||||||
|
<line x1="0" y1="580" x2="1400" y2="580"/>
|
||||||
|
<line x1="0" y1="720" x2="1400" y2="720"/>
|
||||||
|
<line x1="0" y1="860" x2="1400" y2="860"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Ambient glow orbs -->
|
||||||
|
<circle cx="240" cy="350" r="180" fill="#22d3ee" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="160;200;160" dur="8s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="690" cy="360" r="175" fill="#a855f7" opacity="0.05">
|
||||||
|
<animate attributeName="r" values="175;195;175" dur="10s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="1130" cy="350" r="200" fill="#ec4899" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="180;220;180" dur="9s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- TITLE -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<text x="700" y="42" font-family="'JetBrains Mono', monospace" font-size="22" font-weight="800" fill="url(#grad-main)" letter-spacing="6" text-anchor="middle" filter="url(#glow-sm)">VAPORA ARCHITECTURE</text>
|
||||||
|
<text x="700" y="62" font-family="'Inter', sans-serif" font-size="11" fill="#a855f7" opacity="0.6" letter-spacing="3" text-anchor="middle">18 CRATES · 354 TESTS · 100% RUST</text>
|
||||||
|
|
||||||
|
<!-- Layer labels (left side) -->
|
||||||
|
<text x="30" y="115" font-family="'JetBrains Mono', monospace" font-size="10" fill="#22d3ee" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 115)">PRESENTATION</text>
|
||||||
|
<text x="30" y="290" font-family="'JetBrains Mono', monospace" font-size="10" fill="#a855f7" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 290)">SERVICES</text>
|
||||||
|
<text x="30" y="485" font-family="'JetBrains Mono', monospace" font-size="10" fill="#ec4899" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 485)">INTELLIGENCE</text>
|
||||||
|
<text x="30" y="640" font-family="'JetBrains Mono', monospace" font-size="10" fill="#22d3ee" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 640)">DATA</text>
|
||||||
|
<text x="30" y="850" font-family="'JetBrains Mono', monospace" font-size="10" fill="#a855f7" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 850)">PROVIDERS</text>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 1: FRONTEND (y=80) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Frontend card -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="490" y="80" width="420" height="65" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.4" stroke-width="2"/>
|
||||||
|
<rect x="494" y="80" width="412" height="1.5" rx="1" fill="url(#grad-main)" opacity="0.8"/>
|
||||||
|
<text x="700" y="106" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#22d3ee" text-anchor="middle" filter="url(#glow-sm)">Leptos WASM Frontend</text>
|
||||||
|
<text x="700" y="124" font-family="'Inter', sans-serif" font-size="10" fill="#ffffff" opacity="0.5" text-anchor="middle">Kanban Board · Glassmorphism UI · UnoCSS · Reactive Components</text>
|
||||||
|
<!-- Pulse ring -->
|
||||||
|
<rect x="490" y="80" width="420" height="65" rx="8" fill="none" stroke="#22d3ee" stroke-opacity="0.15">
|
||||||
|
<animate attributeName="stroke-opacity" values="0.15;0.3;0.15" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTION: Frontend → Services -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Frontend to Backend -->
|
||||||
|
<path id="path-fe-be" d="M 580 145 L 580 160 Q 580 175 480 175 L 280 175 Q 260 175 260 195 L 260 210" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.8"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-fe-be"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- Frontend to Agents -->
|
||||||
|
<line x1="700" y1="145" x2="700" y2="210" stroke="#a855f7" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.8"><animateMotion dur="2s" repeatCount="indefinite" path="M 700 145 L 700 210"/></use>
|
||||||
|
|
||||||
|
<!-- Frontend to MCP -->
|
||||||
|
<path id="path-fe-mcp" d="M 820 145 L 820 160 Q 820 175 920 175 L 1100 175 Q 1140 175 1140 195 L 1140 210" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.8"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-fe-mcp"/></animateMotion></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 2: SERVICES (y=210) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Backend / Axum API -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="100" y="210" width="310" height="100" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="104" y="210" width="302" height="1.5" rx="1" fill="#22d3ee" opacity="0.6"/>
|
||||||
|
<text x="255" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#22d3ee" text-anchor="middle">Axum Backend API</text>
|
||||||
|
<text x="255" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">40+ REST Endpoints · 161 Tests</text>
|
||||||
|
<!-- Sub-items -->
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.35">
|
||||||
|
<text x="120" y="278">Projects</text>
|
||||||
|
<text x="180" y="278">Tasks</text>
|
||||||
|
<text x="225" y="278">Agents</text>
|
||||||
|
<text x="280" y="278">Workflows</text>
|
||||||
|
<text x="350" y="278">Proposals</text>
|
||||||
|
<text x="120" y="294">Swarm</text>
|
||||||
|
<text x="175" y="294">Metrics</text>
|
||||||
|
<text x="235" y="294">RLM API</text>
|
||||||
|
<text x="300" y="294">WebSocket</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Agent Runtime -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="540" y="210" width="310" height="100" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="544" y="210" width="302" height="1.5" rx="1" fill="#a855f7" opacity="0.6"/>
|
||||||
|
<text x="695" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#a855f7" text-anchor="middle">Agent Runtime</text>
|
||||||
|
<text x="695" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Orchestration · Learning Profiles · 71 Tests</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.35">
|
||||||
|
<text x="560" y="278">Registry</text>
|
||||||
|
<text x="625" y="278">Coordinator</text>
|
||||||
|
<text x="720" y="278">Scoring</text>
|
||||||
|
<text x="785" y="278">Profiles</text>
|
||||||
|
<text x="560" y="294">12 Roles</text>
|
||||||
|
<text x="630" y="294">Health Checks</text>
|
||||||
|
<text x="735" y="294">Recency Bias</text>
|
||||||
|
</g>
|
||||||
|
<!-- Heartbeat animation -->
|
||||||
|
<circle cx="835" cy="225" r="4" fill="#a855f7" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="3;5;3" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.3;0.6;0.3" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- MCP Gateway -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="980" y="210" width="310" height="100" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="984" y="210" width="302" height="1.5" rx="1" fill="#ec4899" opacity="0.6"/>
|
||||||
|
<text x="1135" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#ec4899" text-anchor="middle">MCP Gateway</text>
|
||||||
|
<text x="1135" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Model Context Protocol · Plugin System</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.35">
|
||||||
|
<text x="1000" y="278">Stdio Transport</text>
|
||||||
|
<text x="1105" y="278">SSE Transport</text>
|
||||||
|
<text x="1210" y="278">JSON-RPC</text>
|
||||||
|
<text x="1000" y="294">6 Tools</text>
|
||||||
|
<text x="1060" y="294">Tool Registry</text>
|
||||||
|
<text x="1160" y="294">Schema Validation</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- A2A Protocol (small card overlapping) -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="445" y="280" width="86" height="35" rx="6" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="488" y="300" font-family="'JetBrains Mono', monospace" font-size="9" font-weight="700" fill="#a855f7" opacity="0.6" text-anchor="middle">A2A Protocol</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Services → Intelligence -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Backend → RLM -->
|
||||||
|
<path id="path-be-rlm" d="M 200 310 L 200 380" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 200 310 L 200 380"/></use>
|
||||||
|
|
||||||
|
<!-- Backend → SurrealDB (arco por la derecha para evitar KG) -->
|
||||||
|
<path id="path-be-sdb" d="M 320 310 L 320 340 Q 320 360 360 360 L 420 360 Q 435 360 435 380 Q 435 580 420 580 L 420 585" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.35" stroke-dasharray="4 4"/>
|
||||||
|
|
||||||
|
<!-- Agents → LLM Router -->
|
||||||
|
<line x1="695" y1="310" x2="695" y2="380" stroke="#a855f7" stroke-width="2.4" stroke-opacity="0.3"/>
|
||||||
|
<use href="#particle-purple" opacity="0.8"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 695 310 L 695 380"/></use>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.5"><animateMotion dur="1.5s" begin="0.75s" repeatCount="indefinite" path="M 695 310 L 695 380"/></use>
|
||||||
|
|
||||||
|
<!-- Agents → Swarm -->
|
||||||
|
<path id="path-ag-sw" d="M 800 310 L 800 340 Q 800 355 900 355 L 1050 355 Q 1070 355 1070 375 L 1070 380" fill="none" stroke="#a855f7" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.6"><animateMotion dur="2.2s" repeatCount="indefinite"><mpath href="#path-ag-sw"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- MCP → Agents -->
|
||||||
|
<path id="path-mcp-ag" d="M 1020 310 L 1020 320 Q 1020 332 920 332 L 810 332 Q 800 332 800 320 L 800 310" fill="none" stroke="#ec4899" stroke-width="1.6" stroke-opacity="0.35" stroke-dasharray="3 3"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 3: INTELLIGENCE (y=380) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- RLM Engine -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="60" y="380" width="340" height="130" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="64" y="380" width="332" height="2" rx="1" fill="url(#grad-main)" opacity="0.7"/>
|
||||||
|
<text x="230" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="url(#grad-main)" text-anchor="middle" filter="url(#glow-sm)">RLM Engine</text>
|
||||||
|
<text x="230" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Recursive Language Models · 38 Tests · 17k+ LOC</text>
|
||||||
|
|
||||||
|
<!-- RLM sub-components as mini pills -->
|
||||||
|
<g transform="translate(75, 435)">
|
||||||
|
<!-- Chunking -->
|
||||||
|
<rect x="0" y="0" width="80" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="40" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Chunking</text>
|
||||||
|
<!-- Hybrid Search -->
|
||||||
|
<rect x="90" y="0" width="95" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="137" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Hybrid Search</text>
|
||||||
|
<!-- Dispatcher -->
|
||||||
|
<rect x="195" y="0" width="80" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="235" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Dispatcher</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(75, 465)">
|
||||||
|
<!-- BM25 -->
|
||||||
|
<rect x="0" y="0" width="65" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="32" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">BM25</text>
|
||||||
|
<!-- Semantic -->
|
||||||
|
<rect x="75" y="0" width="70" height="20" rx="3" fill="rgba(168,85,247,0.08)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="110" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Semantic</text>
|
||||||
|
<!-- RRF -->
|
||||||
|
<rect x="155" y="0" width="50" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="180" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">RRF</text>
|
||||||
|
<!-- Sandbox -->
|
||||||
|
<rect x="215" y="0" width="60" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="245" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Sandbox</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Animated search indicator -->
|
||||||
|
<g transform="translate(370, 400)">
|
||||||
|
<circle r="6" fill="none" stroke="#22d3ee" stroke-width="0.8" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="4;8;4" dur="3s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.4;0.1;0.4" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle r="3" fill="#22d3ee" opacity="0.07">
|
||||||
|
<animate attributeName="opacity" values="0.2;0.5;0.2" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- LLM Router -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="500" y="380" width="380" height="130" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="504" y="380" width="372" height="2" rx="1" fill="#a855f7" opacity="0.7"/>
|
||||||
|
<text x="690" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#a855f7" text-anchor="middle" filter="url(#glow-sm)">Multi-IA LLM Router</text>
|
||||||
|
<text x="690" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Budget Enforcement · Cost Tracking · 53 Tests</text>
|
||||||
|
|
||||||
|
<!-- Router sub-components -->
|
||||||
|
<g transform="translate(515, 435)">
|
||||||
|
<rect x="0" y="0" width="95" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="47" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Rule Router</text>
|
||||||
|
<rect x="105" y="0" width="115" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="162" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Budget Manager</text>
|
||||||
|
<rect x="230" y="0" width="110" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="285" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Cost Tracker</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(515, 465)">
|
||||||
|
<rect x="0" y="0" width="95" height="20" rx="3" fill="rgba(168,85,247,0.08)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="47" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Fallback Chain</text>
|
||||||
|
<rect x="105" y="0" width="90" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="150" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Cost Ranker</text>
|
||||||
|
<rect x="205" y="0" width="80" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="245" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Providers</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Routing indicator animation -->
|
||||||
|
<g transform="translate(855, 400)">
|
||||||
|
<line x1="-6" y1="0" x2="6" y2="0" stroke="#a855f7" stroke-width="1.5" opacity="0.5">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="4s" repeatCount="indefinite"/>
|
||||||
|
</line>
|
||||||
|
<line x1="0" y1="-6" x2="0" y2="6" stroke="#ec4899" stroke-width="1.5" opacity="0.5">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="4s" repeatCount="indefinite"/>
|
||||||
|
</line>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Swarm Coordinator -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="980" y="380" width="310" height="130" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="984" y="380" width="302" height="1.5" rx="1" fill="#ec4899" opacity="0.6"/>
|
||||||
|
<text x="1135" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#ec4899" text-anchor="middle" filter="url(#glow-sm)">Swarm Coordinator</text>
|
||||||
|
<text x="1135" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Load Balancing · Prometheus · 6 Tests</text>
|
||||||
|
|
||||||
|
<g transform="translate(995, 435)">
|
||||||
|
<rect x="0" y="0" width="90" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="45" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Assignment</text>
|
||||||
|
<rect x="100" y="0" width="90" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="145" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Filtering</text>
|
||||||
|
<rect x="200" y="0" width="80" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="240" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Metrics</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(995, 465)">
|
||||||
|
<rect x="0" y="0" width="130" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="65" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">success_rate / (1+load)</text>
|
||||||
|
<rect x="140" y="0" width="80" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="180" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Capabilities</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Swarm pulse -->
|
||||||
|
<circle cx="1270" cy="395" r="3" fill="#ec4899" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="2;5;2" dur="2s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.2;0.5;0.2" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- RLM → LLM Router connection -->
|
||||||
|
<path id="path-rlm-llm" d="M 400 445 L 500 445" fill="none" stroke="url(#grad-cyan-purple)" stroke-width="3" stroke-opacity="0.3"/>
|
||||||
|
<use href="#particle-cyan" opacity="0.7"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 400 445 L 500 445"/></use>
|
||||||
|
|
||||||
|
<!-- LLM Router → Swarm connection -->
|
||||||
|
<path d="M 880 445 L 980 445" fill="none" stroke="url(#grad-purple-pink)" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.6"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 880 445 L 980 445"/></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Intelligence → Data -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- RLM → KG -->
|
||||||
|
<path id="path-rlm-kg" d="M 160 510 L 160 575" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 160 510 L 160 575"/></use>
|
||||||
|
|
||||||
|
<!-- RLM → SurrealDB -->
|
||||||
|
<path id="path-rlm-sdb" d="M 300 510 L 300 540 Q 300 555 400 555 L 530 555 Q 545 555 545 575" fill="none" stroke="#22d3ee" stroke-width="2.4" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-cyan" opacity="0.7"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-rlm-sdb"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- LLM Router → Providers (goes down below data) -->
|
||||||
|
<path id="path-llm-providers" d="M 790 510 L 790 725" fill="none" stroke="#a855f7" stroke-width="3" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-purple" opacity="0.8"><animateMotion dur="3s" repeatCount="indefinite" path="M 790 510 L 790 725"/></use>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.5"><animateMotion dur="3s" begin="1.5s" repeatCount="indefinite" path="M 790 510 L 790 725"/></use>
|
||||||
|
|
||||||
|
<!-- Swarm → NATS -->
|
||||||
|
<path id="path-sw-nats" d="M 1135 510 L 1135 575" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 1135 510 L 1135 575"/></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 4: DATA LAYER (y=575) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Knowledge Graph -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="60" y="575" width="260" height="100" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="2"/>
|
||||||
|
<rect x="60" y="575" width="260" height="1.5" rx="1" fill="#22d3ee" opacity="0.5"/>
|
||||||
|
<text x="190" y="600" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Knowledge Graph</text>
|
||||||
|
<text x="190" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.4" text-anchor="middle">Temporal History · Learning Curves · 20 Tests</text>
|
||||||
|
<g transform="translate(75, 630)">
|
||||||
|
<rect x="0" y="0" width="80" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="40" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Executions</text>
|
||||||
|
<rect x="90" y="0" width="70" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="125" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Similarity</text>
|
||||||
|
<rect x="170" y="0" width="60" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="200" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Causal</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SurrealDB -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="420" y="575" width="340" height="100" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="420" y="575" width="340" height="2" rx="1" fill="url(#grad-main)" opacity="0.6"/>
|
||||||
|
<text x="590" y="600" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="url(#grad-main)" text-anchor="middle" filter="url(#glow-sm)">SurrealDB</text>
|
||||||
|
<text x="590" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Multi-Model Database · Multi-Tenant Scopes</text>
|
||||||
|
|
||||||
|
<g transform="translate(435, 630)">
|
||||||
|
<rect x="0" y="0" width="65" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="32" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Projects</text>
|
||||||
|
<rect x="75" y="0" width="50" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="100" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Tasks</text>
|
||||||
|
<rect x="135" y="0" width="55" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="162" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Agents</text>
|
||||||
|
<rect x="200" y="0" width="55" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="227" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Chunks</text>
|
||||||
|
<rect x="265" y="0" width="45" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="287" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">A2A</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- DB activity indicator -->
|
||||||
|
<g transform="translate(735, 590)">
|
||||||
|
<rect x="0" y="0" width="2" height="10" fill="#22d3ee" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="6;12;6" dur="1.2s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="5" y="0" width="2" height="8" fill="#a855f7" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="8;14;8" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="10" y="0" width="2" height="12" fill="#ec4899" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="10;16;10" dur="1s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- KG → SurrealDB -->
|
||||||
|
<line x1="320" y1="630" x2="420" y2="630" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 320 630 L 420 630"/></use>
|
||||||
|
|
||||||
|
<!-- NATS JetStream -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="860" y="575" width="340" height="100" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="2"/>
|
||||||
|
<rect x="860" y="575" width="340" height="1.5" rx="1" fill="#ec4899" opacity="0.5"/>
|
||||||
|
<text x="1030" y="600" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#ec4899" text-anchor="middle" filter="url(#glow-sm)">NATS JetStream</text>
|
||||||
|
<text x="1030" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#ffffff" opacity="0.45" text-anchor="middle">Message Queue · Async Coordination · Pub/Sub</text>
|
||||||
|
|
||||||
|
<g transform="translate(875, 630)">
|
||||||
|
<rect x="0" y="0" width="75" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="37" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Agent Jobs</text>
|
||||||
|
<rect x="85" y="0" width="75" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="122" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Workflows</text>
|
||||||
|
<rect x="170" y="0" width="70" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="205" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Proposals</text>
|
||||||
|
<rect x="250" y="0" width="60" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="280" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">A2A</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Message pulse animation -->
|
||||||
|
<g transform="translate(1125, 590)">
|
||||||
|
<circle r="4" fill="none" stroke="#ffffff" stroke-width="2" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="3;8;3" dur="2s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="1;0.5;1" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle r="3" fill="#ffffff" opacity="0.07">
|
||||||
|
<animate attributeName="opacity" values="0.8;1;0.8" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SurrealDB ↔ NATS bridge line -->
|
||||||
|
<line x1="760" y1="625" x2="860" y2="625" stroke="url(#grad-purple-pink)" stroke-width="0.8" stroke-opacity="0.4" stroke-dasharray="4 3"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Data → Providers -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Central provider trunk (from LLM Router, already drawn) -->
|
||||||
|
<!-- Branch to each provider -->
|
||||||
|
<path id="path-to-claude" d="M 790 725 Q 790 750 500 750 L 245 750 Q 225 750 225 785" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-to-claude"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-openai" d="M 790 725 Q 790 760 600 760 L 555 760 Q 545 760 545 785" fill="none" stroke="#a855f7" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.6"><animateMotion dur="2s" repeatCount="indefinite"><mpath href="#path-to-openai"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-gemini" d="M 790 725 Q 790 770 810 770 L 855 770 Q 865 770 865 785" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.6"><animateMotion dur="2.2s" repeatCount="indefinite"><mpath href="#path-to-gemini"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-ollama" d="M 790 725 Q 790 750 900 750 L 1155 750 Q 1175 750 1175 785" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="2.8s" repeatCount="indefinite"><mpath href="#path-to-ollama"/></animateMotion></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 5: LLM PROVIDERS (y=810) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Claude -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="100" y="785" width="250" height="55" rx="6" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="225" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Anthropic Claude</text>
|
||||||
|
<text x="225" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.4" text-anchor="middle">Opus · Sonnet · Haiku</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- OpenAI -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="420" y="785" width="250" height="55" rx="6" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="545" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#a855f7" text-anchor="middle">OpenAI</text>
|
||||||
|
<text x="545" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.4" text-anchor="middle">GPT-4 · GPT-4o · GPT-3.5</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Gemini -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="740" y="785" width="250" height="55" rx="6" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="865" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#ec4899" text-anchor="middle">Google Gemini</text>
|
||||||
|
<text x="865" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.4" text-anchor="middle">2.0 Pro · Flash · 1.5 Pro</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Ollama -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="1060" y="785" width="250" height="55" rx="6" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="1185" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Ollama (Local)</text>
|
||||||
|
<text x="1185" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#ffffff" opacity="0.4" text-anchor="middle">Llama · Mistral · CodeLlama</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- SUPPORTING CRATES (bottom strip) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<g transform="translate(0, 882)">
|
||||||
|
<rect x="60" y="0" width="1280" height="50" rx="6" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="700" y="16" font-family="'JetBrains Mono', monospace" font-size="9" fill="#a855f7" opacity="0.7" text-anchor="middle" letter-spacing="2">SUPPORTING CRATES</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="10" opacity="0.6" text-anchor="middle">
|
||||||
|
<text x="130" y="36" fill="#22d3ee">vapora-shared</text>
|
||||||
|
<text x="260" y="36" fill="#a855f7">vapora-tracking</text>
|
||||||
|
<text x="400" y="36" fill="#ec4899">vapora-telemetry</text>
|
||||||
|
<text x="540" y="36" fill="#22d3ee">vapora-analytics</text>
|
||||||
|
<text x="680" y="36" fill="#a855f7">vapora-worktree</text>
|
||||||
|
<text x="820" y="36" fill="#ec4899">vapora-doc-lifecycle</text>
|
||||||
|
<text x="975" y="36" fill="#22d3ee">vapora-workflow-engine</text>
|
||||||
|
<text x="1140" y="36" fill="#a855f7">vapora-cli</text>
|
||||||
|
<text x="1250" y="36" fill="#ec4899">vapora-leptos-ui</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- OBSERVABILITY STRIP (right edge) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<g transform="translate(1340, 80)">
|
||||||
|
<rect x="0" y="0" width="4" height="790" rx="2" fill="url(#grad-vertical)" opacity="0.3">
|
||||||
|
<animate attributeName="opacity" values="0.2;0.4;0.2" dur="5s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<text x="15" y="400" font-family="'JetBrains Mono', monospace" font-size="9" fill="#a855f7" opacity="0.6" letter-spacing="2" text-anchor="middle" transform="rotate(90 15 400)">PROMETHEUS · GRAFANA · OPENTELEMETRY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- FOOTER -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<text x="700" y="970" font-family="'JetBrains Mono', monospace" font-size="11" font-weight="700" fill="url(#grad-main)" text-anchor="middle" opacity="0.7" letter-spacing="3">VAPORA v1.2.0</text>
|
||||||
|
<text x="700" y="993" font-family="'Inter', sans-serif" font-size="9" fill="#a855f7" opacity="0.6" text-anchor="middle" letter-spacing="1">Evaporate complexity · Full-Stack Rust · Production Ready</text>
|
||||||
|
|
||||||
|
<!-- Bottom gradient bar -->
|
||||||
|
<rect x="400" y="1005" width="600" height="2" rx="1" fill="url(#grad-main)" opacity="0.3"/>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 42 KiB |
576
assets/web/vapora_architecture_white.svg
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 1020" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700;800&family=Inter:wght@400;500;600&display=swap');
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Brand gradients -->
|
||||||
|
<linearGradient id="grad-main" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee"/>
|
||||||
|
<stop offset="50%" stop-color="#a855f7"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-cyan-purple" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee"/>
|
||||||
|
<stop offset="100%" stop-color="#a855f7"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-purple-pink" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#a855f7"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-vertical" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.8"/>
|
||||||
|
<stop offset="50%" stop-color="#a855f7" stop-opacity="0.5"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899" stop-opacity="0.3"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-cyan" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.12"/>
|
||||||
|
<stop offset="100%" stop-color="#22d3ee" stop-opacity="0.03"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-purple" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#a855f7" stop-opacity="0.12"/>
|
||||||
|
<stop offset="100%" stop-color="#a855f7" stop-opacity="0.03"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad-card-pink" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" stop-color="#ec4899" stop-opacity="0.12"/>
|
||||||
|
<stop offset="100%" stop-color="#ec4899" stop-opacity="0.03"/>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<!-- Glow filters -->
|
||||||
|
<filter id="glow-sm">
|
||||||
|
<feGaussianBlur stdDeviation="0.5" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glow-md">
|
||||||
|
<feGaussianBlur stdDeviation="4" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glow-lg">
|
||||||
|
<feGaussianBlur stdDeviation="6" result="blur"/>
|
||||||
|
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
<filter id="glass-card">
|
||||||
|
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"/>
|
||||||
|
<feOffset dx="0" dy="1" result="shadow"/>
|
||||||
|
<feFlood flood-color="#000" flood-opacity="0.3" result="color"/>
|
||||||
|
<feComposite in="color" in2="shadow" operator="in" result="shadow"/>
|
||||||
|
<feMerge><feMergeNode in="shadow"/><feMergeNode in="SourceGraphic"/></feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<!-- Animated particle marker -->
|
||||||
|
<circle id="particle-cyan" r="3" fill="#22d3ee" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-purple" r="3" fill="#a855f7" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-pink" r="3" fill="#ec4899" filter="url(#glow-md)"/>
|
||||||
|
<circle id="particle-sm-cyan" r="2" fill="#22d3ee" filter="url(#glow-sm)"/>
|
||||||
|
<circle id="particle-sm-purple" r="2" fill="#a855f7" filter="url(#glow-sm)"/>
|
||||||
|
<circle id="particle-sm-pink" r="2" fill="#ec4899" filter="url(#glow-sm)"/>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- BACKGROUND -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<rect width="1400" height="1020" fill="#ffffff"/>
|
||||||
|
|
||||||
|
<!-- Subtle tech grid -->
|
||||||
|
<g opacity="0.08" stroke="#22d3ee" stroke-width="0.5">
|
||||||
|
<line x1="0" y1="0" x2="1400" y2="0"><animate attributeName="y1" values="0;1020" dur="60s" repeatCount="indefinite"/><animate attributeName="y2" values="0;1020" dur="60s" repeatCount="indefinite"/></line>
|
||||||
|
<line x1="100" y1="0" x2="100" y2="1020"/>
|
||||||
|
<line x1="250" y1="0" x2="250" y2="1020"/>
|
||||||
|
<line x1="400" y1="0" x2="400" y2="1020"/>
|
||||||
|
<line x1="550" y1="0" x2="550" y2="1020"/>
|
||||||
|
<line x1="700" y1="0" x2="700" y2="1020"/>
|
||||||
|
<line x1="850" y1="0" x2="850" y2="1020"/>
|
||||||
|
<line x1="1000" y1="0" x2="1000" y2="1020"/>
|
||||||
|
<line x1="1150" y1="0" x2="1150" y2="1020"/>
|
||||||
|
<line x1="1300" y1="0" x2="1300" y2="1020"/>
|
||||||
|
<line x1="0" y1="130" x2="1400" y2="130"/>
|
||||||
|
<line x1="0" y1="260" x2="1400" y2="260"/>
|
||||||
|
<line x1="0" y1="420" x2="1400" y2="420"/>
|
||||||
|
<line x1="0" y1="580" x2="1400" y2="580"/>
|
||||||
|
<line x1="0" y1="720" x2="1400" y2="720"/>
|
||||||
|
<line x1="0" y1="860" x2="1400" y2="860"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Ambient glow orbs -->
|
||||||
|
<circle cx="240" cy="350" r="180" fill="#22d3ee" opacity="0.05">
|
||||||
|
<animate attributeName="r" values="160;200;160" dur="8s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="690" cy="360" r="175" fill="#a855f7" opacity="0.04">
|
||||||
|
<animate attributeName="r" values="175;195;175" dur="10s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle cx="1130" cy="350" r="200" fill="#ec4899" opacity="0.05">
|
||||||
|
<animate attributeName="r" values="180;220;180" dur="9s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- TITLE -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<text x="700" y="42" font-family="'JetBrains Mono', monospace" font-size="22" font-weight="800" fill="url(#grad-main)" letter-spacing="6" text-anchor="middle" filter="url(#glow-sm)">VAPORA ARCHITECTURE</text>
|
||||||
|
<text x="700" y="62" font-family="'Inter', sans-serif" font-size="11" fill="#a855f7" opacity="0.6" letter-spacing="3" text-anchor="middle">18 CRATES · 354 TESTS · 100% RUST</text>
|
||||||
|
|
||||||
|
<!-- Layer labels (left side) -->
|
||||||
|
<text x="30" y="115" font-family="'JetBrains Mono', monospace" font-size="10" fill="#22d3ee" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 115)">PRESENTATION</text>
|
||||||
|
<text x="30" y="290" font-family="'JetBrains Mono', monospace" font-size="10" fill="#a855f7" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 290)">SERVICES</text>
|
||||||
|
<text x="30" y="485" font-family="'JetBrains Mono', monospace" font-size="10" fill="#ec4899" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 485)">INTELLIGENCE</text>
|
||||||
|
<text x="30" y="640" font-family="'JetBrains Mono', monospace" font-size="10" fill="#22d3ee" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 640)">DATA</text>
|
||||||
|
<text x="30" y="850" font-family="'JetBrains Mono', monospace" font-size="10" fill="#a855f7" opacity="0.7" letter-spacing="2" transform="rotate(-90 30 850)">PROVIDERS</text>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 1: FRONTEND (y=80) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Frontend card -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="490" y="80" width="420" height="65" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.4" stroke-width="1"/>
|
||||||
|
<rect x="494" y="80" width="412" height="1.5" rx="1" fill="url(#grad-main)" opacity="0.8"/>
|
||||||
|
<text x="700" y="106" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#22d3ee" text-anchor="middle" filter="url(#glow-sm)">Leptos WASM Frontend</text>
|
||||||
|
<text x="700" y="124" font-family="'Inter', sans-serif" font-size="10" fill="#1f2937" opacity="0.85" text-anchor="middle">Kanban Board · Glassmorphism UI · UnoCSS · Reactive Components</text>
|
||||||
|
<!-- Pulse ring -->
|
||||||
|
<rect x="490" y="80" width="420" height="65" rx="8" fill="none" stroke="#22d3ee" stroke-opacity="0.15">
|
||||||
|
<animate attributeName="stroke-opacity" values="0.15;0.3;0.15" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTION: Frontend → Services -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Frontend to Backend -->
|
||||||
|
<path id="path-fe-be" d="M 580 145 L 580 160 Q 580 175 480 175 L 280 175 Q 260 175 260 195 L 260 210" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.8"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-fe-be"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- Frontend to Agents -->
|
||||||
|
<line x1="700" y1="145" x2="700" y2="210" stroke="#a855f7" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.8"><animateMotion dur="2s" repeatCount="indefinite" path="M 700 145 L 700 210"/></use>
|
||||||
|
|
||||||
|
<!-- Frontend to MCP -->
|
||||||
|
<path id="path-fe-mcp" d="M 820 145 L 820 160 Q 820 175 920 175 L 1100 175 Q 1140 175 1140 195 L 1140 210" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.8"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-fe-mcp"/></animateMotion></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 2: SERVICES (y=210) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Backend / Axum API -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="100" y="210" width="310" height="100" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="104" y="210" width="302" height="1.5" rx="1" fill="#22d3ee" opacity="0.6"/>
|
||||||
|
<text x="255" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#22d3ee" text-anchor="middle">Axum Backend API</text>
|
||||||
|
<text x="255" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">40+ REST Endpoints · 161 Tests</text>
|
||||||
|
<!-- Sub-items -->
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.65">
|
||||||
|
<text x="120" y="278">Projects</text>
|
||||||
|
<text x="180" y="278">Tasks</text>
|
||||||
|
<text x="225" y="278">Agents</text>
|
||||||
|
<text x="280" y="278">Workflows</text>
|
||||||
|
<text x="350" y="278">Proposals</text>
|
||||||
|
<text x="120" y="294">Swarm</text>
|
||||||
|
<text x="175" y="294">Metrics</text>
|
||||||
|
<text x="235" y="294">RLM API</text>
|
||||||
|
<text x="300" y="294">WebSocket</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Agent Runtime -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="540" y="210" width="310" height="100" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="544" y="210" width="302" height="1.5" rx="1" fill="#a855f7" opacity="0.6"/>
|
||||||
|
<text x="695" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#a855f7" text-anchor="middle">Agent Runtime</text>
|
||||||
|
<text x="695" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Orchestration · Learning Profiles · 71 Tests</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.65">
|
||||||
|
<text x="560" y="278">Registry</text>
|
||||||
|
<text x="625" y="278">Coordinator</text>
|
||||||
|
<text x="720" y="278">Scoring</text>
|
||||||
|
<text x="785" y="278">Profiles</text>
|
||||||
|
<text x="560" y="294">12 Roles</text>
|
||||||
|
<text x="630" y="294">Health Checks</text>
|
||||||
|
<text x="735" y="294">Recency Bias</text>
|
||||||
|
</g>
|
||||||
|
<!-- Heartbeat animation -->
|
||||||
|
<circle cx="835" cy="225" r="4" fill="#a855f7" opacity="0.04">
|
||||||
|
<animate attributeName="r" values="3;5;3" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.3;0.6;0.3" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- MCP Gateway -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="980" y="210" width="310" height="100" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="984" y="210" width="302" height="1.5" rx="1" fill="#ec4899" opacity="0.6"/>
|
||||||
|
<text x="1135" y="237" font-family="'JetBrains Mono', monospace" font-size="13" font-weight="700" fill="#ec4899" text-anchor="middle">MCP Gateway</text>
|
||||||
|
<text x="1135" y="256" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Model Context Protocol · Plugin System</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.65">
|
||||||
|
<text x="1000" y="278">Stdio Transport</text>
|
||||||
|
<text x="1105" y="278">SSE Transport</text>
|
||||||
|
<text x="1210" y="278">JSON-RPC</text>
|
||||||
|
<text x="1000" y="294">6 Tools</text>
|
||||||
|
<text x="1060" y="294">Tool Registry</text>
|
||||||
|
<text x="1160" y="294">Schema Validation</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- A2A Protocol (small card overlapping) -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="445" y="280" width="86" height="35" rx="6" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="488" y="300" font-family="'JetBrains Mono', monospace" font-size="9" font-weight="700" fill="#a855f7" opacity="0.6" text-anchor="middle">A2A Protocol</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Services → Intelligence -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Backend → RLM -->
|
||||||
|
<path id="path-be-rlm" d="M 200 310 L 200 380" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 200 310 L 200 380"/></use>
|
||||||
|
|
||||||
|
<!-- Backend → SurrealDB (arco por la derecha para evitar KG) -->
|
||||||
|
<path id="path-be-sdb" d="M 320 310 L 320 340 Q 320 360 360 360 L 420 360 Q 435 360 435 380 Q 435 580 420 580 L 420 585" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.35" stroke-dasharray="4 4"/>
|
||||||
|
|
||||||
|
<!-- Agents → LLM Router -->
|
||||||
|
<line x1="695" y1="310" x2="695" y2="380" stroke="#a855f7" stroke-width="2.4" stroke-opacity="0.3"/>
|
||||||
|
<use href="#particle-purple" opacity="0.8"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 695 310 L 695 380"/></use>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.5"><animateMotion dur="1.5s" begin="0.75s" repeatCount="indefinite" path="M 695 310 L 695 380"/></use>
|
||||||
|
|
||||||
|
<!-- Agents → Swarm -->
|
||||||
|
<path id="path-ag-sw" d="M 800 310 L 800 340 Q 800 355 900 355 L 1050 355 Q 1070 355 1070 375 L 1070 380" fill="none" stroke="#a855f7" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.6"><animateMotion dur="2.2s" repeatCount="indefinite"><mpath href="#path-ag-sw"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- MCP → Agents -->
|
||||||
|
<path id="path-mcp-ag" d="M 1020 310 L 1020 320 Q 1020 332 920 332 L 810 332 Q 800 332 800 320 L 800 310" fill="none" stroke="#ec4899" stroke-width="1.6" stroke-opacity="0.35" stroke-dasharray="3 3"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 3: INTELLIGENCE (y=380) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- RLM Engine -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="60" y="380" width="340" height="130" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="64" y="380" width="332" height="2" rx="1" fill="url(#grad-main)" opacity="0.7"/>
|
||||||
|
<text x="230" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="url(#grad-main)" text-anchor="middle" filter="url(#glow-sm)">RLM Engine</text>
|
||||||
|
<text x="230" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Recursive Language Models · 38 Tests · 17k+ LOC</text>
|
||||||
|
|
||||||
|
<!-- RLM sub-components as mini pills -->
|
||||||
|
<g transform="translate(75, 435)">
|
||||||
|
<!-- Chunking -->
|
||||||
|
<rect x="0" y="0" width="80" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="40" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Chunking</text>
|
||||||
|
<!-- Hybrid Search -->
|
||||||
|
<rect x="90" y="0" width="95" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="137" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Hybrid Search</text>
|
||||||
|
<!-- Dispatcher -->
|
||||||
|
<rect x="195" y="0" width="80" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="235" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Dispatcher</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(75, 465)">
|
||||||
|
<!-- BM25 -->
|
||||||
|
<rect x="0" y="0" width="65" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="32" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">BM25</text>
|
||||||
|
<!-- Semantic -->
|
||||||
|
<rect x="75" y="0" width="70" height="20" rx="3" fill="rgba(168,85,247,0.08)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="110" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Semantic</text>
|
||||||
|
<!-- RRF -->
|
||||||
|
<rect x="155" y="0" width="50" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="180" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">RRF</text>
|
||||||
|
<!-- Sandbox -->
|
||||||
|
<rect x="215" y="0" width="60" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="245" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Sandbox</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Animated search indicator -->
|
||||||
|
<g transform="translate(370, 400)">
|
||||||
|
<circle r="6" fill="none" stroke="#22d3ee" stroke-width="0.8" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="4;8;4" dur="3s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.4;0.1;0.4" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle r="3" fill="#22d3ee" opacity="0.07">
|
||||||
|
<animate attributeName="opacity" values="0.2;0.5;0.2" dur="3s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- LLM Router -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="500" y="380" width="380" height="130" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="504" y="380" width="372" height="2" rx="1" fill="#a855f7" opacity="0.7"/>
|
||||||
|
<text x="690" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#a855f7" text-anchor="middle" filter="url(#glow-sm)">Multi-IA LLM Router</text>
|
||||||
|
<text x="690" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Budget Enforcement · Cost Tracking · 53 Tests</text>
|
||||||
|
|
||||||
|
<!-- Router sub-components -->
|
||||||
|
<g transform="translate(515, 435)">
|
||||||
|
<rect x="0" y="0" width="95" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="47" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Rule Router</text>
|
||||||
|
<rect x="105" y="0" width="115" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="162" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Budget Manager</text>
|
||||||
|
<rect x="230" y="0" width="110" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="285" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Cost Tracker</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(515, 465)">
|
||||||
|
<rect x="0" y="0" width="95" height="20" rx="3" fill="rgba(168,85,247,0.08)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="47" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Fallback Chain</text>
|
||||||
|
<rect x="105" y="0" width="90" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="150" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Cost Ranker</text>
|
||||||
|
<rect x="205" y="0" width="80" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="245" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Providers</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Routing indicator animation -->
|
||||||
|
<g transform="translate(855, 400)">
|
||||||
|
<line x1="-6" y1="0" x2="6" y2="0" stroke="#a855f7" stroke-width="1.5" opacity="0.5">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="4s" repeatCount="indefinite"/>
|
||||||
|
</line>
|
||||||
|
<line x1="0" y1="-6" x2="0" y2="6" stroke="#ec4899" stroke-width="1.5" opacity="0.5">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" values="0;360" dur="4s" repeatCount="indefinite"/>
|
||||||
|
</line>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Swarm Coordinator -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="980" y="380" width="310" height="130" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="984" y="380" width="302" height="1.5" rx="1" fill="#ec4899" opacity="0.6"/>
|
||||||
|
<text x="1135" y="405" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#ec4899" text-anchor="middle" filter="url(#glow-sm)">Swarm Coordinator</text>
|
||||||
|
<text x="1135" y="422" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Load Balancing · Prometheus · 6 Tests</text>
|
||||||
|
|
||||||
|
<g transform="translate(995, 435)">
|
||||||
|
<rect x="0" y="0" width="90" height="22" rx="4" fill="rgba(236,72,153,0.12)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="45" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#ec4899" opacity="0.8" text-anchor="middle" dominant-baseline="central">Assignment</text>
|
||||||
|
<rect x="100" y="0" width="90" height="22" rx="4" fill="rgba(34,211,238,0.12)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="145" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#22d3ee" opacity="0.8" text-anchor="middle" dominant-baseline="central">Filtering</text>
|
||||||
|
<rect x="200" y="0" width="80" height="22" rx="4" fill="rgba(168,85,247,0.12)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.5"/>
|
||||||
|
<text x="240" y="11" font-family="'JetBrains Mono', monospace" font-size="7" fill="#a855f7" opacity="0.8" text-anchor="middle" dominant-baseline="central">Metrics</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(995, 465)">
|
||||||
|
<rect x="0" y="0" width="130" height="20" rx="3" fill="rgba(236,72,153,0.08)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="65" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">success_rate / (1+load)</text>
|
||||||
|
<rect x="140" y="0" width="80" height="20" rx="3" fill="rgba(34,211,238,0.08)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="180" y="10" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Capabilities</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Swarm pulse -->
|
||||||
|
<circle cx="1270" cy="395" r="3" fill="#ec4899" opacity="0.04">
|
||||||
|
<animate attributeName="r" values="2;5;2" dur="2s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="0.2;0.5;0.2" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- RLM → LLM Router connection -->
|
||||||
|
<path id="path-rlm-llm" d="M 400 445 L 500 445" fill="none" stroke="url(#grad-cyan-purple)" stroke-width="3" stroke-opacity="0.3"/>
|
||||||
|
<use href="#particle-cyan" opacity="0.7"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 400 445 L 500 445"/></use>
|
||||||
|
|
||||||
|
<!-- LLM Router → Swarm connection -->
|
||||||
|
<path d="M 880 445 L 980 445" fill="none" stroke="url(#grad-purple-pink)" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.6"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 880 445 L 980 445"/></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Intelligence → Data -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- RLM → KG -->
|
||||||
|
<path id="path-rlm-kg" d="M 160 510 L 160 575" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 160 510 L 160 575"/></use>
|
||||||
|
|
||||||
|
<!-- RLM → SurrealDB -->
|
||||||
|
<path id="path-rlm-sdb" d="M 300 510 L 300 540 Q 300 555 400 555 L 530 555 Q 545 555 545 575" fill="none" stroke="#22d3ee" stroke-width="2.4" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-cyan" opacity="0.7"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-rlm-sdb"/></animateMotion></use>
|
||||||
|
|
||||||
|
<!-- LLM Router → Providers (goes down below data) -->
|
||||||
|
<path id="path-llm-providers" d="M 790 510 L 790 725" fill="none" stroke="#a855f7" stroke-width="3" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-purple" opacity="0.8"><animateMotion dur="3s" repeatCount="indefinite" path="M 790 510 L 790 725"/></use>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.5"><animateMotion dur="3s" begin="1.5s" repeatCount="indefinite" path="M 790 510 L 790 725"/></use>
|
||||||
|
|
||||||
|
<!-- Swarm → NATS -->
|
||||||
|
<path id="path-sw-nats" d="M 1135 510 L 1135 575" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.25"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.7"><animateMotion dur="1.8s" repeatCount="indefinite" path="M 1135 510 L 1135 575"/></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 4: DATA LAYER (y=575) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Knowledge Graph -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="60" y="575" width="260" height="100" rx="8" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="1"/>
|
||||||
|
<rect x="60" y="575" width="260" height="1.5" rx="1" fill="#22d3ee" opacity="0.5"/>
|
||||||
|
<text x="190" y="600" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Knowledge Graph</text>
|
||||||
|
<text x="190" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.7" text-anchor="middle">Temporal History · Learning Curves · 20 Tests</text>
|
||||||
|
<g transform="translate(75, 630)">
|
||||||
|
<rect x="0" y="0" width="80" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="40" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Executions</text>
|
||||||
|
<rect x="90" y="0" width="70" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="125" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Similarity</text>
|
||||||
|
<rect x="170" y="0" width="60" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="200" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Causal</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SurrealDB -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="420" y="575" width="340" height="100" rx="8" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.4" stroke-width="1.2"/>
|
||||||
|
<rect x="420" y="575" width="340" height="2" rx="1" fill="url(#grad-main)" opacity="0.6"/>
|
||||||
|
<text x="590" y="600" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="url(#grad-main)" text-anchor="middle" filter="url(#glow-sm)">SurrealDB</text>
|
||||||
|
<text x="590" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Multi-Model Database · Multi-Tenant Scopes</text>
|
||||||
|
|
||||||
|
<g transform="translate(435, 630)">
|
||||||
|
<rect x="0" y="0" width="65" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="32" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Projects</text>
|
||||||
|
<rect x="75" y="0" width="50" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="100" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Tasks</text>
|
||||||
|
<rect x="135" y="0" width="55" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="162" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Agents</text>
|
||||||
|
<rect x="200" y="0" width="55" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="227" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Chunks</text>
|
||||||
|
<rect x="265" y="0" width="45" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="287" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">A2A</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- DB activity indicator -->
|
||||||
|
<g transform="translate(735, 590)">
|
||||||
|
<rect x="0" y="0" width="2" height="10" fill="#22d3ee" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="6;12;6" dur="1.2s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="5" y="0" width="2" height="8" fill="#a855f7" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="8;14;8" dur="1.5s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<rect x="10" y="0" width="2" height="12" fill="#ec4899" opacity="0.4">
|
||||||
|
<animate attributeName="height" values="10;16;10" dur="1s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- KG → SurrealDB -->
|
||||||
|
<line x1="320" y1="630" x2="420" y2="630" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="1.5s" repeatCount="indefinite" path="M 320 630 L 420 630"/></use>
|
||||||
|
|
||||||
|
<!-- NATS JetStream -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="860" y="575" width="340" height="100" rx="8" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.35" stroke-width="1"/>
|
||||||
|
<rect x="860" y="575" width="340" height="1.5" rx="1" fill="#ec4899" opacity="0.5"/>
|
||||||
|
<text x="1030" y="600" font-family="'JetBrains Mono', monospace" font-size="14" font-weight="700" fill="#ec4899" text-anchor="middle" filter="url(#glow-sm)">NATS JetStream</text>
|
||||||
|
<text x="1030" y="617" font-family="'Inter', sans-serif" font-size="9" fill="#1f2937" opacity="0.75" text-anchor="middle">Message Queue · Async Coordination · Pub/Sub</text>
|
||||||
|
|
||||||
|
<g transform="translate(875, 630)">
|
||||||
|
<rect x="0" y="0" width="75" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="37" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">Agent Jobs</text>
|
||||||
|
<rect x="85" y="0" width="75" height="18" rx="3" fill="rgba(34,211,238,0.1)" stroke="#22d3ee" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="122" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#22d3ee" opacity="0.6" text-anchor="middle" dominant-baseline="central">Workflows</text>
|
||||||
|
<rect x="170" y="0" width="70" height="18" rx="3" fill="rgba(168,85,247,0.1)" stroke="#a855f7" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="205" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#a855f7" opacity="0.6" text-anchor="middle" dominant-baseline="central">Proposals</text>
|
||||||
|
<rect x="250" y="0" width="60" height="18" rx="3" fill="rgba(236,72,153,0.1)" stroke="#ec4899" stroke-opacity="0.2" stroke-width="0.5"/>
|
||||||
|
<text x="280" y="9" font-family="'Inter', sans-serif" font-size="7" fill="#ec4899" opacity="0.6" text-anchor="middle" dominant-baseline="central">A2A</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Message pulse animation -->
|
||||||
|
<g transform="translate(1125, 590)">
|
||||||
|
<circle r="4" fill="none" stroke="#22d3ee" stroke-width="1.5" opacity="0.07">
|
||||||
|
<animate attributeName="r" values="3;8;3" dur="2s" repeatCount="indefinite"/>
|
||||||
|
<animate attributeName="opacity" values="1;0.4;1" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
<circle r="2" fill="#22d3ee" opacity="0.07">
|
||||||
|
<animate attributeName="opacity" values="0.7;1;0.7" dur="2s" repeatCount="indefinite"/>
|
||||||
|
</circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- SurrealDB ↔ NATS bridge line -->
|
||||||
|
<line x1="760" y1="625" x2="860" y2="625" stroke="url(#grad-purple-pink)" stroke-width="0.8" stroke-opacity="0.4" stroke-dasharray="4 3"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- CONNECTIONS: Data → Providers -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Central provider trunk (from LLM Router, already drawn) -->
|
||||||
|
<!-- Branch to each provider -->
|
||||||
|
<path id="path-to-claude" d="M 790 725 Q 790 750 500 750 L 245 750 Q 225 750 225 785" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="2.5s" repeatCount="indefinite"><mpath href="#path-to-claude"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-openai" d="M 790 725 Q 790 760 600 760 L 555 760 Q 545 760 545 785" fill="none" stroke="#a855f7" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-purple" opacity="0.6"><animateMotion dur="2s" repeatCount="indefinite"><mpath href="#path-to-openai"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-gemini" d="M 790 725 Q 790 770 810 770 L 855 770 Q 865 770 865 785" fill="none" stroke="#ec4899" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-pink" opacity="0.6"><animateMotion dur="2.2s" repeatCount="indefinite"><mpath href="#path-to-gemini"/></animateMotion></use>
|
||||||
|
|
||||||
|
<path id="path-to-ollama" d="M 790 725 Q 790 750 900 750 L 1155 750 Q 1175 750 1175 785" fill="none" stroke="#22d3ee" stroke-width="2" stroke-opacity="0.2"/>
|
||||||
|
<use href="#particle-sm-cyan" opacity="0.6"><animateMotion dur="2.8s" repeatCount="indefinite"><mpath href="#path-to-ollama"/></animateMotion></use>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- ROW 5: LLM PROVIDERS (y=810) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<!-- Claude -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="100" y="785" width="250" height="55" rx="6" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="225" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Anthropic Claude</text>
|
||||||
|
<text x="225" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.7" text-anchor="middle">Opus · Sonnet · Haiku</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- OpenAI -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="420" y="785" width="250" height="55" rx="6" fill="url(#grad-card-purple)" stroke="#a855f7" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="545" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#a855f7" text-anchor="middle">OpenAI</text>
|
||||||
|
<text x="545" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.7" text-anchor="middle">GPT-4 · GPT-4o · GPT-3.5</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Gemini -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="740" y="785" width="250" height="55" rx="6" fill="url(#grad-card-pink)" stroke="#ec4899" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="865" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#ec4899" text-anchor="middle">Google Gemini</text>
|
||||||
|
<text x="865" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.7" text-anchor="middle">2.0 Pro · Flash · 1.5 Pro</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Ollama -->
|
||||||
|
<g filter="url(#glass-card)">
|
||||||
|
<rect x="1060" y="785" width="250" height="55" rx="6" fill="url(#grad-card-cyan)" stroke="#22d3ee" stroke-opacity="0.3" stroke-width="0.8"/>
|
||||||
|
<text x="1185" y="810" font-family="'JetBrains Mono', monospace" font-size="12" font-weight="700" fill="#22d3ee" text-anchor="middle">Ollama (Local)</text>
|
||||||
|
<text x="1185" y="827" font-family="'Inter', sans-serif" font-size="8" fill="#1f2937" opacity="0.7" text-anchor="middle">Llama · Mistral · CodeLlama</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- SUPPORTING CRATES (bottom strip) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<g transform="translate(0, 882)">
|
||||||
|
<rect x="60" y="0" width="1280" height="50" rx="6" fill="rgba(168,85,247,0.04)" stroke="#a855f7" stroke-opacity="0.1" stroke-width="0.5"/>
|
||||||
|
<text x="700" y="16" font-family="'JetBrains Mono', monospace" font-size="9" fill="#a855f7" opacity="0.7" text-anchor="middle" letter-spacing="2">SUPPORTING CRATES</text>
|
||||||
|
<g font-family="'Inter', sans-serif" font-size="10" opacity="0.6" text-anchor="middle">
|
||||||
|
<text x="130" y="36" fill="#22d3ee">vapora-shared</text>
|
||||||
|
<text x="260" y="36" fill="#a855f7">vapora-tracking</text>
|
||||||
|
<text x="400" y="36" fill="#ec4899">vapora-telemetry</text>
|
||||||
|
<text x="540" y="36" fill="#22d3ee">vapora-analytics</text>
|
||||||
|
<text x="680" y="36" fill="#a855f7">vapora-worktree</text>
|
||||||
|
<text x="820" y="36" fill="#ec4899">vapora-doc-lifecycle</text>
|
||||||
|
<text x="975" y="36" fill="#22d3ee">vapora-workflow-engine</text>
|
||||||
|
<text x="1140" y="36" fill="#a855f7">vapora-cli</text>
|
||||||
|
<text x="1250" y="36" fill="#ec4899">vapora-leptos-ui</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- OBSERVABILITY STRIP (right edge) -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<g transform="translate(1340, 80)">
|
||||||
|
<rect x="0" y="0" width="4" height="790" rx="2" fill="url(#grad-vertical)" opacity="0.3">
|
||||||
|
<animate attributeName="opacity" values="0.2;0.4;0.2" dur="5s" repeatCount="indefinite"/>
|
||||||
|
</rect>
|
||||||
|
<text x="15" y="400" font-family="'JetBrains Mono', monospace" font-size="9" fill="#a855f7" opacity="0.6" letter-spacing="2" text-anchor="middle" transform="rotate(90 15 400)">PROMETHEUS · GRAFANA · OPENTELEMETRY</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<!-- FOOTER -->
|
||||||
|
<!-- ═══════════════════════════════════════ -->
|
||||||
|
<text x="700" y="970" font-family="'JetBrains Mono', monospace" font-size="11" font-weight="700" fill="url(#grad-main)" text-anchor="middle" opacity="0.7" letter-spacing="3">VAPORA v1.2.0</text>
|
||||||
|
<text x="700" y="993" font-family="'Inter', sans-serif" font-size="9" fill="#a855f7" opacity="0.6" text-anchor="middle" letter-spacing="1">Evaporate complexity · Full-Stack Rust · Production Ready</text>
|
||||||
|
|
||||||
|
<!-- Bottom gradient bar -->
|
||||||
|
<rect x="400" y="1005" width="600" height="2" rx="1" fill="url(#grad-main)" opacity="0.3"/>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 42 KiB |
119
assets/web/vapora_white.svg
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="170 40 590 300" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
|
||||||
|
<defs>
|
||||||
|
<!-- Google Fonts import -->
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@800&display=swap');
|
||||||
|
</style>
|
||||||
|
<linearGradient id="techGradWhite" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:#22d3ee;stop-opacity:1"/>
|
||||||
|
<stop offset="50%" style="stop-color:#a855f7;stop-opacity:1"/>
|
||||||
|
<stop offset="100%" style="stop-color:#ec4899;stop-opacity:1"/>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="vertGradWhite" x1="0%" y1="100%" x2="0%" y2="0%">
|
||||||
|
<stop offset="0%" style="stop-color:#22d3ee;stop-opacity:1"/>
|
||||||
|
<stop offset="50%" style="stop-color:#a855f7;stop-opacity:0.8"/>
|
||||||
|
<stop offset="100%" style="stop-color:#ec4899;stop-opacity:0.4"/>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<filter id="techGlowWhite">
|
||||||
|
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<filter id="strongGlowWhite">
|
||||||
|
<feGaussianBlur stdDeviation="4" result="coloredBlur"/>
|
||||||
|
<feMerge>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="coloredBlur"/>
|
||||||
|
<feMergeNode in="SourceGraphic"/>
|
||||||
|
</feMerge>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<filter id="glassWhite">
|
||||||
|
<feGaussianBlur in="SourceGraphic" stdDeviation="0.5" result="blur"/>
|
||||||
|
<feColorMatrix in="blur" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" result="goo"/>
|
||||||
|
<feBlend in="SourceGraphic" in2="goo"/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Fondo blanco -->
|
||||||
|
<rect width="800" height="400" fill="#ffffff"/>
|
||||||
|
|
||||||
|
<!-- Grid de fondo técnico sutil -->
|
||||||
|
<g opacity="0.08" stroke="#22d3ee" stroke-width="1">
|
||||||
|
<line x1="0" y1="133" x2="800" y2="133"/>
|
||||||
|
<line x1="0" y1="200" x2="800" y2="200"/>
|
||||||
|
<line x1="0" y1="267" x2="800" y2="267"/>
|
||||||
|
<line x1="133" y1="0" x2="133" y2="400"/>
|
||||||
|
<line x1="267" y1="0" x2="267" y2="400"/>
|
||||||
|
<line x1="400" y1="0" x2="400" y2="400"/>
|
||||||
|
<line x1="533" y1="0" x2="533" y2="400"/>
|
||||||
|
<line x1="667" y1="0" x2="667" y2="400"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Símbolo técnico: flujo de datos ascendente -->
|
||||||
|
<g transform="translate(267, 280)">
|
||||||
|
<rect x="-25" y="0" width="50" height="6.67" fill="url(#techGradWhite)" opacity="0.8" rx="3.33"/>
|
||||||
|
|
||||||
|
<path d="M 0 0 L 0 -50 L 8.33 -58 L -8.33 -75 L 8.33 -92 L -8.33 -108 L 8.33 -125 L 0 -133 L 0 -200" stroke="url(#vertGradWhite)" stroke-width="5" fill="none" stroke-linecap="round" stroke-linejoin="round" filter="url(#techGlowWhite)"/>
|
||||||
|
|
||||||
|
<path d="M -33 0 L -33 -42 L -30 -58 L -37 -75 L -30 -92 L -37 -108 L -33 -125 L -33 -167" stroke="#22d3ee" stroke-width="3.33" fill="none" stroke-linecap="round" opacity="0.6" filter="url(#techGlowWhite)"/>
|
||||||
|
|
||||||
|
<path d="M -58 0 L -58 -33 L -53 -50 L -63 -67 L -53 -83 L -63 -100 L -58 -117 L -58 -142" stroke="#a855f7" stroke-width="2.5" fill="none" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
|
||||||
|
<path d="M 33 0 L 33 -42 L 30 -58 L 37 -75 L 30 -92 L 37 -108 L 33 -125 L 33 -167" stroke="#ec4899" stroke-width="3.33" fill="none" stroke-linecap="round" opacity="0.6" filter="url(#techGlowWhite)"/>
|
||||||
|
|
||||||
|
<path d="M 58 0 L 58 -33 L 53 -50 L 63 -67 L 53 -83 L 63 -100 L 58 -117 L 58 -142" stroke="#22d3ee" stroke-width="2.5" fill="none" stroke-linecap="round" opacity="0.5"/>
|
||||||
|
|
||||||
|
<circle cx="0" cy="-67" r="5" fill="#22d3ee" filter="url(#strongGlowWhite)"/>
|
||||||
|
<circle cx="0" cy="-100" r="4.17" fill="#a855f7" filter="url(#strongGlowWhite)"/>
|
||||||
|
<circle cx="0" cy="-133" r="3.33" fill="#ec4899" filter="url(#strongGlowWhite)"/>
|
||||||
|
|
||||||
|
<circle cx="-33" cy="-83" r="3.33" fill="#22d3ee" opacity="0.7"/>
|
||||||
|
<circle cx="33" cy="-92" r="3.33" fill="#ec4899" opacity="0.7"/>
|
||||||
|
<circle cx="-58" cy="-58" r="2.5" fill="#a855f7" opacity="0.5"/>
|
||||||
|
<circle cx="58" cy="-67" r="2.5" fill="#22d3ee" opacity="0.5"/>
|
||||||
|
|
||||||
|
<polygon points="0,-158 5,-162 5,-167 0,-170 -5,-167 -5,-162" stroke="#22d3ee" fill="none" stroke-width="1.67" opacity="0.6"/>
|
||||||
|
<polygon points="-42,-117 -37,-120 -37,-125 -42,-128 -47,-125 -47,-120" stroke="#a855f7" fill="none" stroke-width="1.67" opacity="0.5"/>
|
||||||
|
<polygon points="42,-125 47,-128 47,-133 42,-137 37,-133 37,-128" stroke="#ec4899" fill="none" stroke-width="1.67" opacity="0.5"/>
|
||||||
|
|
||||||
|
<line x1="-33" y1="-100" x2="-8" y2="-100" stroke="#22d3ee" stroke-width="0.83" opacity="0.4"/>
|
||||||
|
<line x1="8" y1="-117" x2="33" y2="-117" stroke="#ec4899" stroke-width="0.83" opacity="0.4"/>
|
||||||
|
<line x1="-58" y1="-83" x2="-37" y2="-83" stroke="#a855f7" stroke-width="0.83" opacity="0.3"/>
|
||||||
|
<line x1="37" y1="-92" x2="58" y2="-92" stroke="#22d3ee" stroke-width="0.83" opacity="0.3"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Texto VAPORA -->
|
||||||
|
<g filter="url(#glassWhite)">
|
||||||
|
<text x="550" y="207" font-family="'JetBrains Mono', 'Fira Code', monospace" font-size="90" font-weight="800" fill="url(#techGradWhite)" letter-spacing="5" text-anchor="middle">
|
||||||
|
VAPORA
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<text x="550" y="207" font-family="'JetBrains Mono', 'Fira Code', monospace" font-size="90" font-weight="800" fill="none" stroke="rgba(0,0,0,0.1)" stroke-width="0.83" letter-spacing="5" text-anchor="middle">
|
||||||
|
VAPORA
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Glow en texto -->
|
||||||
|
<text x="550" y="207" font-family="'JetBrains Mono', 'Fira Code', monospace" font-size="90" font-weight="800" fill="url(#techGradWhite)" letter-spacing="5" filter="url(#techGlowWhite)" opacity="0.3" text-anchor="middle">
|
||||||
|
VAPORA
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<!-- Tagline -->
|
||||||
|
<text x="550" y="240" font-family="'Inter', sans-serif" font-size="20" fill="#a855f7" opacity="0.8" letter-spacing="0.25em" text-anchor="middle">
|
||||||
|
Evaporate complexity
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<!-- Indicador técnico decorativo -->
|
||||||
|
<g transform="translate(550, 280)">
|
||||||
|
<rect x="0" y="0" width="2" height="13.33" fill="#22d3ee" opacity="0.6"/>
|
||||||
|
<rect x="6.67" y="0" width="2" height="16.67" fill="#a855f7" opacity="0.6"/>
|
||||||
|
<rect x="13.33" y="0" width="2" height="10" fill="#ec4899" opacity="0.6"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.0 KiB |
@ -0,0 +1,402 @@
|
|||||||
|
# ADR-008: Recursive Language Models (RLM) Integration
|
||||||
|
|
||||||
|
**Date**: 2026-02-16
|
||||||
|
**Status**: Accepted
|
||||||
|
**Deciders**: VAPORA Team
|
||||||
|
**Technical Story**: Phase 9 - RLM as Core Foundation
|
||||||
|
|
||||||
|
## Context and Problem Statement
|
||||||
|
|
||||||
|
VAPORA's agent system relied on **direct LLM calls** for all reasoning tasks, which created fundamental limitations:
|
||||||
|
|
||||||
|
1. **Context window limitations**: Single LLM calls fail beyond 50-100k tokens (context rot)
|
||||||
|
2. **No knowledge reuse**: Historical executions were not semantically searchable
|
||||||
|
3. **Single-shot reasoning**: No distributed analysis across document chunks
|
||||||
|
4. **Cost inefficiency**: Processing entire documents repeatedly instead of relevant chunks
|
||||||
|
5. **No incremental learning**: Agents couldn't learn from past successful solutions
|
||||||
|
|
||||||
|
**Question**: How do we enable long-context reasoning, knowledge reuse, and distributed LLM processing in VAPORA?
|
||||||
|
|
||||||
|
## Decision Drivers
|
||||||
|
|
||||||
|
**Must Have:**
|
||||||
|
- Handle documents >100k tokens without context rot
|
||||||
|
- Semantic search over historical executions
|
||||||
|
- Distributed reasoning across document chunks
|
||||||
|
- Integration with existing SurrealDB + NATS architecture
|
||||||
|
- Support multiple LLM providers (OpenAI, Claude, Ollama)
|
||||||
|
|
||||||
|
**Should Have:**
|
||||||
|
- Hybrid search (keyword + semantic)
|
||||||
|
- Cost tracking per provider
|
||||||
|
- Prometheus metrics
|
||||||
|
- Sandboxed execution environment
|
||||||
|
|
||||||
|
**Nice to Have:**
|
||||||
|
- WASM-based fast execution tier
|
||||||
|
- Docker warm pool for complex tasks
|
||||||
|
|
||||||
|
## Considered Options
|
||||||
|
|
||||||
|
### Option 1: RAG (Retrieval-Augmented Generation) Only
|
||||||
|
|
||||||
|
**Approach**: Traditional RAG with vector embeddings + SurrealDB
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- Simple to implement
|
||||||
|
- Well-understood pattern
|
||||||
|
- Good for basic Q&A
|
||||||
|
|
||||||
|
**Cons:**
|
||||||
|
- ❌ No distributed reasoning (single LLM call)
|
||||||
|
- ❌ Keyword search limitations (only semantic)
|
||||||
|
- ❌ No execution sandbox
|
||||||
|
- ❌ Limited to simple retrieval tasks
|
||||||
|
|
||||||
|
### Option 2: LangChain/LlamaIndex Integration
|
||||||
|
|
||||||
|
**Approach**: Use existing framework (LangChain or LlamaIndex)
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- Pre-built components
|
||||||
|
- Active community
|
||||||
|
- Many integrations
|
||||||
|
|
||||||
|
**Cons:**
|
||||||
|
- ❌ Python-based (VAPORA is Rust-first)
|
||||||
|
- ❌ Heavy dependencies
|
||||||
|
- ❌ Less control over implementation
|
||||||
|
- ❌ Tight coupling to framework abstractions
|
||||||
|
|
||||||
|
### Option 3: Recursive Language Models (RLM) - **SELECTED**
|
||||||
|
|
||||||
|
**Approach**: Custom Rust implementation with distributed reasoning, hybrid search, and sandboxed execution
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- ✅ Native Rust (zero-cost abstractions, safety)
|
||||||
|
- ✅ Hybrid search (BM25 + semantic + RRF fusion)
|
||||||
|
- ✅ Distributed LLM calls across chunks
|
||||||
|
- ✅ Sandboxed execution (WASM + Docker)
|
||||||
|
- ✅ Full control over implementation
|
||||||
|
- ✅ Reuses existing VAPORA patterns (SurrealDB, NATS, Prometheus)
|
||||||
|
|
||||||
|
**Cons:**
|
||||||
|
- ⚠️ More initial implementation effort
|
||||||
|
- ⚠️ Maintaining custom codebase
|
||||||
|
|
||||||
|
**Decision**: **Option 3 - RLM Custom Implementation**
|
||||||
|
|
||||||
|
## Decision Outcome
|
||||||
|
|
||||||
|
### Chosen Solution: Recursive Language Models (RLM)
|
||||||
|
|
||||||
|
Implement a **native Rust RLM system** as a foundational VAPORA component, providing:
|
||||||
|
|
||||||
|
1. **Chunking**: Fixed, Semantic, Code-aware strategies
|
||||||
|
2. **Hybrid Search**: BM25 (Tantivy) + Semantic (embeddings) + RRF fusion
|
||||||
|
3. **Distributed Reasoning**: Parallel LLM calls across relevant chunks
|
||||||
|
4. **Sandboxed Execution**: WASM tier (<10ms) + Docker tier (80-150ms)
|
||||||
|
5. **Knowledge Graph**: Store execution history with learning curves
|
||||||
|
6. **Multi-Provider**: OpenAI, Claude, Gemini, Ollama support
|
||||||
|
|
||||||
|
### Architecture Overview
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ RLM Engine │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||||
|
│ │ Chunking │ │ Hybrid Search│ │ Dispatcher │ │
|
||||||
|
│ │ │ │ │ │ │ │
|
||||||
|
│ │ • Fixed │ │ • BM25 │ │ • Parallel │ │
|
||||||
|
│ │ • Semantic │ │ • Semantic │ │ LLM calls │ │
|
||||||
|
│ │ • Code │ │ • RRF Fusion │ │ • Aggregation│ │
|
||||||
|
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||||
|
│ │ Storage │ │ Sandbox │ │ Metrics │ │
|
||||||
|
│ │ │ │ │ │ │ │
|
||||||
|
│ │ • SurrealDB │ │ • WASM │ │ • Prometheus │ │
|
||||||
|
│ │ • Chunks │ │ • Docker │ │ • Costs │ │
|
||||||
|
│ │ • Buffers │ │ • Auto-tier │ │ • Latency │ │
|
||||||
|
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Implementation Details
|
||||||
|
|
||||||
|
**Crate**: `vapora-rlm` (17,000+ LOC)
|
||||||
|
|
||||||
|
**Key Components:**
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// 1. Chunking
|
||||||
|
pub enum ChunkingStrategy {
|
||||||
|
Fixed, // Fixed-size chunks with overlap
|
||||||
|
Semantic, // Unicode-aware, sentence boundaries
|
||||||
|
Code, // AST-based (Rust, Python, JS)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Hybrid Search
|
||||||
|
pub struct HybridSearch {
|
||||||
|
bm25_index: Arc<BM25Index>, // Tantivy in-memory
|
||||||
|
storage: Arc<dyn Storage>, // SurrealDB
|
||||||
|
config: HybridSearchConfig, // RRF weights
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. LLM Dispatch
|
||||||
|
pub struct LLMDispatcher {
|
||||||
|
client: Option<Arc<dyn LLMClient>>, // Multi-provider
|
||||||
|
config: DispatchConfig, // Aggregation strategy
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Sandbox
|
||||||
|
pub enum SandboxTier {
|
||||||
|
WASM, // <10ms, WASI-compatible commands
|
||||||
|
Docker, // <150ms, full compatibility
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Database Schema** (SCHEMALESS for flexibility):
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Chunks (from documents)
|
||||||
|
DEFINE TABLE rlm_chunks SCHEMALESS;
|
||||||
|
DEFINE INDEX idx_rlm_chunks_chunk_id ON TABLE rlm_chunks COLUMNS chunk_id UNIQUE;
|
||||||
|
DEFINE INDEX idx_rlm_chunks_doc_id ON TABLE rlm_chunks COLUMNS doc_id;
|
||||||
|
|
||||||
|
-- Execution History (for learning)
|
||||||
|
DEFINE TABLE rlm_executions SCHEMALESS;
|
||||||
|
DEFINE INDEX idx_rlm_executions_execution_id ON TABLE rlm_executions COLUMNS execution_id UNIQUE;
|
||||||
|
DEFINE INDEX idx_rlm_executions_doc_id ON TABLE rlm_executions COLUMNS doc_id;
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key Decision**: Use **SCHEMALESS** instead of SCHEMAFULL tables to avoid conflicts with SurrealDB's auto-generated `id` fields.
|
||||||
|
|
||||||
|
### Production Usage
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use vapora_rlm::{RLMEngine, ChunkingConfig, EmbeddingConfig};
|
||||||
|
use vapora_llm_router::providers::OpenAIClient;
|
||||||
|
|
||||||
|
// Setup LLM client
|
||||||
|
let llm_client = Arc::new(OpenAIClient::new(
|
||||||
|
api_key, "gpt-4".to_string(),
|
||||||
|
4096, 0.7, 5.0, 15.0
|
||||||
|
)?);
|
||||||
|
|
||||||
|
// Configure RLM
|
||||||
|
let config = RLMEngineConfig {
|
||||||
|
chunking: ChunkingConfig {
|
||||||
|
strategy: ChunkingStrategy::Semantic,
|
||||||
|
chunk_size: 1000,
|
||||||
|
overlap: 200,
|
||||||
|
},
|
||||||
|
embedding: Some(EmbeddingConfig::openai_small()),
|
||||||
|
auto_rebuild_bm25: true,
|
||||||
|
max_chunks_per_doc: 10_000,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create engine
|
||||||
|
let engine = RLMEngine::with_llm_client(
|
||||||
|
storage, bm25_index, llm_client, Some(config)
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Usage
|
||||||
|
let chunks = engine.load_document(doc_id, content, None).await?;
|
||||||
|
let results = engine.query(doc_id, "error handling", None, 5).await?;
|
||||||
|
let response = engine.dispatch_subtask(doc_id, "Analyze code", None, 5).await?;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
### Positive
|
||||||
|
|
||||||
|
**Performance:**
|
||||||
|
- ✅ Handles 100k+ line documents without context rot
|
||||||
|
- ✅ Query latency: ~90ms average (100 queries benchmark)
|
||||||
|
- ✅ WASM tier: <10ms for simple commands
|
||||||
|
- ✅ Docker tier: <150ms from warm pool
|
||||||
|
- ✅ Full workflow: <30s for 10k lines (2728 chunks)
|
||||||
|
|
||||||
|
**Functionality:**
|
||||||
|
- ✅ Hybrid search outperforms pure semantic or BM25 alone
|
||||||
|
- ✅ Distributed reasoning reduces hallucinations
|
||||||
|
- ✅ Knowledge Graph enables learning from past executions
|
||||||
|
- ✅ Multi-provider support (OpenAI, Claude, Ollama)
|
||||||
|
|
||||||
|
**Quality:**
|
||||||
|
- ✅ 38/38 tests passing (100% pass rate)
|
||||||
|
- ✅ 0 clippy warnings
|
||||||
|
- ✅ Comprehensive E2E, performance, security tests
|
||||||
|
- ✅ Production-ready with real persistence (no stubs)
|
||||||
|
|
||||||
|
**Cost Efficiency:**
|
||||||
|
- ✅ Chunk-based processing reduces token usage
|
||||||
|
- ✅ Cost tracking per provider and task
|
||||||
|
- ✅ Local Ollama option for development (free)
|
||||||
|
|
||||||
|
### Negative
|
||||||
|
|
||||||
|
**Complexity:**
|
||||||
|
- ⚠️ Additional component to maintain (17k+ LOC)
|
||||||
|
- ⚠️ Learning curve for distributed reasoning patterns
|
||||||
|
- ⚠️ More moving parts (chunking, BM25, embeddings, dispatch)
|
||||||
|
|
||||||
|
**Infrastructure:**
|
||||||
|
- ⚠️ Requires SurrealDB for persistence
|
||||||
|
- ⚠️ Requires embedding provider (OpenAI/Ollama)
|
||||||
|
- ⚠️ Optional Docker for full sandbox tier
|
||||||
|
|
||||||
|
**Performance Trade-offs:**
|
||||||
|
- ⚠️ Load time ~22s for 10k lines (chunking + embedding + indexing)
|
||||||
|
- ⚠️ BM25 rebuild time proportional to document size
|
||||||
|
- ⚠️ Memory usage: ~25MB per WASM instance, ~100-300MB per Docker container
|
||||||
|
|
||||||
|
### Risks and Mitigations
|
||||||
|
|
||||||
|
| Risk | Mitigation | Status |
|
||||||
|
|------|-----------|--------|
|
||||||
|
| SurrealDB schema conflicts | Use SCHEMALESS tables | ✅ Resolved |
|
||||||
|
| BM25 index performance | In-memory Tantivy, auto-rebuild | ✅ Verified |
|
||||||
|
| LLM provider costs | Cost tracking, local Ollama option | ✅ Implemented |
|
||||||
|
| Sandbox escape | WASM isolation, Docker security tests | ✅ 13/13 tests passing |
|
||||||
|
| Context window limits | Chunking + hybrid search + aggregation | ✅ Handles 100k+ tokens |
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
### Test Coverage
|
||||||
|
|
||||||
|
```
|
||||||
|
Basic integration: 4/4 ✅ (100%)
|
||||||
|
E2E integration: 9/9 ✅ (100%)
|
||||||
|
Security: 13/13 ✅ (100%)
|
||||||
|
Performance: 8/8 ✅ (100%)
|
||||||
|
Debug tests: 4/4 ✅ (100%)
|
||||||
|
───────────────────────────────────
|
||||||
|
Total: 38/38 ✅ (100%)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Benchmarks
|
||||||
|
|
||||||
|
```
|
||||||
|
Query Latency (100 queries):
|
||||||
|
Average: 90.6ms
|
||||||
|
P50: 87.5ms
|
||||||
|
P95: 88.3ms
|
||||||
|
P99: 91.7ms
|
||||||
|
|
||||||
|
Large Document (10k lines):
|
||||||
|
Load: ~22s (2728 chunks)
|
||||||
|
Query: ~565ms
|
||||||
|
Full workflow: <30s
|
||||||
|
|
||||||
|
BM25 Index:
|
||||||
|
Build time: ~100ms for 1000 docs
|
||||||
|
Search: <1ms for most queries
|
||||||
|
```
|
||||||
|
|
||||||
|
### Integration Points
|
||||||
|
|
||||||
|
**Existing VAPORA Components:**
|
||||||
|
- ✅ `vapora-llm-router`: LLM client integration
|
||||||
|
- ✅ `vapora-knowledge-graph`: Execution history persistence
|
||||||
|
- ✅ `vapora-shared`: Common error types and models
|
||||||
|
- ✅ SurrealDB: Persistent storage backend
|
||||||
|
- ✅ Prometheus: Metrics export
|
||||||
|
|
||||||
|
**New Integration Surface:**
|
||||||
|
```rust
|
||||||
|
// Backend API
|
||||||
|
POST /api/v1/rlm/analyze
|
||||||
|
{
|
||||||
|
"content": "...",
|
||||||
|
"query": "...",
|
||||||
|
"strategy": "semantic"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Agent Coordinator
|
||||||
|
let rlm_result = rlm_engine.dispatch_subtask(
|
||||||
|
doc_id, task.description, None, 5
|
||||||
|
).await?;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Decisions
|
||||||
|
|
||||||
|
- **ADR-003**: Multi-provider LLM routing (Phase 6 dependency)
|
||||||
|
- **ADR-005**: Knowledge Graph temporal modeling (RLM execution history)
|
||||||
|
- **ADR-006**: Prometheus metrics standardization (RLM metrics)
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
**Implementation:**
|
||||||
|
- `crates/vapora-rlm/` - Full RLM implementation
|
||||||
|
- `crates/vapora-rlm/PRODUCTION.md` - Production setup guide
|
||||||
|
- `crates/vapora-rlm/examples/` - Working examples
|
||||||
|
- `migrations/008_rlm_schema.surql` - Database schema
|
||||||
|
|
||||||
|
**External:**
|
||||||
|
- [Tantivy](https://github.com/quickwit-oss/tantivy) - BM25 full-text search
|
||||||
|
- [RRF Paper](https://plg.uwaterloo.ca/~gvcormac/cormacksigir09-rrf.pdf) - Reciprocal Rank Fusion
|
||||||
|
- [WASM Security Model](https://webassembly.org/docs/security/)
|
||||||
|
|
||||||
|
**Tests:**
|
||||||
|
- `tests/e2e_integration.rs` - End-to-end workflow tests
|
||||||
|
- `tests/performance_test.rs` - Performance benchmarks
|
||||||
|
- `tests/security_test.rs` - Sandbox security validation
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
**Why SCHEMALESS vs SCHEMAFULL?**
|
||||||
|
|
||||||
|
Initial implementation used SCHEMAFULL with explicit `id` field definitions:
|
||||||
|
```sql
|
||||||
|
DEFINE TABLE rlm_chunks SCHEMAFULL;
|
||||||
|
DEFINE FIELD id ON TABLE rlm_chunks TYPE record<rlm_chunks>; -- ❌ Conflict
|
||||||
|
```
|
||||||
|
|
||||||
|
This caused data persistence failures because SurrealDB auto-generates `id` fields. Changed to SCHEMALESS:
|
||||||
|
```sql
|
||||||
|
DEFINE TABLE rlm_chunks SCHEMALESS; -- ✅ Works
|
||||||
|
DEFINE INDEX idx_rlm_chunks_chunk_id ON TABLE rlm_chunks COLUMNS chunk_id UNIQUE;
|
||||||
|
```
|
||||||
|
|
||||||
|
Indexes still work with SCHEMALESS, providing necessary performance without schema conflicts.
|
||||||
|
|
||||||
|
**Why Hybrid Search?**
|
||||||
|
|
||||||
|
Pure BM25 (keyword):
|
||||||
|
- ✅ Fast, exact matches
|
||||||
|
- ❌ Misses semantic similarity
|
||||||
|
|
||||||
|
Pure Semantic (embeddings):
|
||||||
|
- ✅ Understands meaning
|
||||||
|
- ❌ Expensive, misses exact keywords
|
||||||
|
|
||||||
|
Hybrid (BM25 + Semantic + RRF):
|
||||||
|
- ✅ Best of both worlds
|
||||||
|
- ✅ Reciprocal Rank Fusion combines rankings optimally
|
||||||
|
- ✅ Empirically outperforms either alone
|
||||||
|
|
||||||
|
**Why Custom Implementation vs Framework?**
|
||||||
|
|
||||||
|
Frameworks (LangChain, LlamaIndex):
|
||||||
|
- Python-based (VAPORA is Rust)
|
||||||
|
- Heavy abstractions
|
||||||
|
- Less control
|
||||||
|
- Dependency lock-in
|
||||||
|
|
||||||
|
Custom Rust RLM:
|
||||||
|
- Native performance
|
||||||
|
- Full control
|
||||||
|
- Zero-cost abstractions
|
||||||
|
- Direct integration with VAPORA patterns
|
||||||
|
|
||||||
|
**Trade-off accepted**: More initial effort for long-term maintainability and performance.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Supersedes**: None (new decision)
|
||||||
|
**Amended by**: None
|
||||||
|
**Last Updated**: 2026-02-16
|
||||||
540
docs/guides/rlm-usage-guide.md
Normal file
@ -0,0 +1,540 @@
|
|||||||
|
# RLM Usage Guide - Recursive Language Models
|
||||||
|
|
||||||
|
Guide completa para usar y adaptar el sistema RLM en VAPORA.
|
||||||
|
|
||||||
|
## Tabla de Contenidos
|
||||||
|
|
||||||
|
- [Introducción](#introducción)
|
||||||
|
- [Conceptos Básicos](#conceptos-básicos)
|
||||||
|
- [Configuración](#configuración)
|
||||||
|
- [Casos de Uso](#casos-de-uso)
|
||||||
|
- [Adaptación](#adaptación)
|
||||||
|
- [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
|
## Introducción
|
||||||
|
|
||||||
|
### ¿Qué es RLM?
|
||||||
|
|
||||||
|
RLM (Recursive Language Models) es un sistema de razonamiento distribuido que permite:
|
||||||
|
|
||||||
|
- **Procesar documentos grandes** (>100k tokens) sin limitaciones de contexto
|
||||||
|
- **Búsqueda híbrida** (keywords + semántica) con RRF fusion
|
||||||
|
- **Razonamiento distribuido** mediante llamadas LLM paralelas
|
||||||
|
- **Aprendizaje incremental** desde historial de ejecuciones
|
||||||
|
|
||||||
|
### ¿Cuándo usar RLM?
|
||||||
|
|
||||||
|
**Usa RLM cuando:**
|
||||||
|
- ✅ Documentos >50k tokens
|
||||||
|
- ✅ Necesitas búsqueda semántica + keywords
|
||||||
|
- ✅ Razonamiento sobre múltiples partes del documento
|
||||||
|
- ✅ Reutilizar soluciones de ejecuciones pasadas
|
||||||
|
|
||||||
|
**No uses RLM cuando:**
|
||||||
|
- ❌ Documentos pequeños (<10k tokens) - usa LLM directo
|
||||||
|
- ❌ Solo necesitas chat simple
|
||||||
|
- ❌ Latencia crítica (<100ms) - usa cache/embeddings directos
|
||||||
|
|
||||||
|
## Conceptos Básicos
|
||||||
|
|
||||||
|
### 1. Chunking (Fragmentación)
|
||||||
|
|
||||||
|
Divide documentos en chunks (fragmentos) manejables:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use vapora_rlm::chunking::{ChunkingConfig, ChunkingStrategy};
|
||||||
|
|
||||||
|
// Fixed: Tamaño fijo con overlap
|
||||||
|
let config = ChunkingConfig {
|
||||||
|
strategy: ChunkingStrategy::Fixed,
|
||||||
|
chunk_size: 1000, // 1000 caracteres por chunk
|
||||||
|
overlap: 200, // 200 caracteres de overlap
|
||||||
|
};
|
||||||
|
|
||||||
|
// Semantic: Respeta límites de oraciones
|
||||||
|
let config = ChunkingConfig {
|
||||||
|
strategy: ChunkingStrategy::Semantic,
|
||||||
|
chunk_size: 1000,
|
||||||
|
overlap: 200,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Code: Usa AST para código fuente
|
||||||
|
let config = ChunkingConfig {
|
||||||
|
strategy: ChunkingStrategy::Code,
|
||||||
|
chunk_size: 1500,
|
||||||
|
overlap: 300,
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Guía de selección:**
|
||||||
|
|
||||||
|
| Tipo de contenido | Estrategia recomendada | Chunk size |
|
||||||
|
|-------------------|------------------------|------------|
|
||||||
|
| Prosa, docs | Semantic | 1000-2000 |
|
||||||
|
| Código fuente | Code | 1500-3000 |
|
||||||
|
| Logs, datos | Fixed | 500-1000 |
|
||||||
|
| Mixto | Semantic | 1000-1500 |
|
||||||
|
|
||||||
|
### 2. Hybrid Search (Búsqueda Híbrida)
|
||||||
|
|
||||||
|
Combina BM25 (keywords) + embeddings (semántica) + RRF:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Automático - RLM maneja la búsqueda híbrida
|
||||||
|
let results = engine.query(
|
||||||
|
doc_id, // ID del documento
|
||||||
|
"error handling", // Query (keywords)
|
||||||
|
None, // Embedding opcional
|
||||||
|
5, // Top 5 resultados
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
// Resultados incluyen scores híbridos
|
||||||
|
for result in results {
|
||||||
|
println!("Score: {}", result.score); // Score RRF combinado
|
||||||
|
println!("BM25: {:?}", result.bm25_score);
|
||||||
|
println!("Semantic: {:?}", result.semantic_score);
|
||||||
|
println!("Content: {}", result.chunk.content);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Scores:**
|
||||||
|
- `score`: Score RRF final (mayor = mejor)
|
||||||
|
- `bm25_score`: Score keyword (TF-IDF based)
|
||||||
|
- `semantic_score`: Score semántico (cosine similarity)
|
||||||
|
|
||||||
|
### 3. LLM Dispatch (Razonamiento Distribuido)
|
||||||
|
|
||||||
|
Envía chunks relevantes al LLM para análisis:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let response = engine.dispatch_subtask(
|
||||||
|
doc_id, // Documento
|
||||||
|
"Explain error handling", // Tarea para el LLM
|
||||||
|
None, // Embedding query opcional
|
||||||
|
5, // Top 5 chunks relevantes
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
println!("LLM Response: {}", response.text);
|
||||||
|
println!("Tokens: {} in, {} out",
|
||||||
|
response.total_input_tokens,
|
||||||
|
response.total_output_tokens
|
||||||
|
);
|
||||||
|
println!("Cost: ${:.4}",
|
||||||
|
(response.total_input_tokens as f64 * 5.0 / 1_000_000.0) +
|
||||||
|
(response.total_output_tokens as f64 * 15.0 / 1_000_000.0)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuración
|
||||||
|
|
||||||
|
### Setup Básico (Development)
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use std::sync::Arc;
|
||||||
|
use surrealdb::engine::remote::ws::Ws;
|
||||||
|
use surrealdb::opt::auth::Root;
|
||||||
|
use surrealdb::Surreal;
|
||||||
|
use vapora_llm_router::providers::OllamaClient;
|
||||||
|
use vapora_rlm::search::bm25::BM25Index;
|
||||||
|
use vapora_rlm::storage::SurrealDBStorage;
|
||||||
|
use vapora_rlm::RLMEngine;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> anyhow::Result<()> {
|
||||||
|
// 1. SurrealDB
|
||||||
|
let db = Surreal::new::<Ws>("127.0.0.1:8000").await?;
|
||||||
|
db.signin(Root {
|
||||||
|
username: "root",
|
||||||
|
password: "root",
|
||||||
|
}).await?;
|
||||||
|
db.use_ns("dev").use_db("rlm").await?;
|
||||||
|
|
||||||
|
// 2. Ollama (local, gratis)
|
||||||
|
let llm_client = Arc::new(OllamaClient::new(
|
||||||
|
"http://localhost:11434".to_string(),
|
||||||
|
"llama3.2".to_string(),
|
||||||
|
4096, 0.7,
|
||||||
|
)?);
|
||||||
|
|
||||||
|
// 3. Storage y BM25
|
||||||
|
let storage = Arc::new(SurrealDBStorage::new(db));
|
||||||
|
let bm25_index = Arc::new(BM25Index::new()?);
|
||||||
|
|
||||||
|
// 4. RLM Engine
|
||||||
|
let engine = RLMEngine::with_llm_client(
|
||||||
|
storage,
|
||||||
|
bm25_index,
|
||||||
|
llm_client,
|
||||||
|
None, // Config por defecto
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setup Producción (OpenAI)
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use vapora_llm_router::providers::OpenAIClient;
|
||||||
|
use vapora_rlm::engine::RLMEngineConfig;
|
||||||
|
use vapora_rlm::chunking::{ChunkingConfig, ChunkingStrategy};
|
||||||
|
use vapora_rlm::embeddings::EmbeddingConfig;
|
||||||
|
|
||||||
|
// LLM client
|
||||||
|
let llm_client = Arc::new(OpenAIClient::new(
|
||||||
|
std::env::var("OPENAI_API_KEY")?,
|
||||||
|
"gpt-4".to_string(),
|
||||||
|
4096, 0.7,
|
||||||
|
5.0, // $5 per 1M input tokens
|
||||||
|
15.0, // $15 per 1M output tokens
|
||||||
|
)?);
|
||||||
|
|
||||||
|
// Config optimizada
|
||||||
|
let config = RLMEngineConfig {
|
||||||
|
chunking: ChunkingConfig {
|
||||||
|
strategy: ChunkingStrategy::Semantic,
|
||||||
|
chunk_size: 1500,
|
||||||
|
overlap: 300,
|
||||||
|
},
|
||||||
|
embedding: Some(EmbeddingConfig::openai_small()),
|
||||||
|
auto_rebuild_bm25: true,
|
||||||
|
max_chunks_per_doc: 10_000,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Engine con config
|
||||||
|
let engine = RLMEngine::with_llm_client(
|
||||||
|
storage,
|
||||||
|
bm25_index,
|
||||||
|
llm_client,
|
||||||
|
Some(config),
|
||||||
|
)?;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Casos de Uso
|
||||||
|
|
||||||
|
### 1. Análisis de Código (Code Review)
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Cargar repositorio
|
||||||
|
let code = std::fs::read_to_string("src/main.rs")?;
|
||||||
|
let chunks = engine.load_document("repo/main.rs", &code, None).await?;
|
||||||
|
|
||||||
|
// Buscar errores potenciales
|
||||||
|
let results = engine.query(
|
||||||
|
"repo/main.rs",
|
||||||
|
"unsafe unwrap panic error", // Keywords
|
||||||
|
None,
|
||||||
|
10
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
// Analizar con LLM
|
||||||
|
let review = engine.dispatch_subtask(
|
||||||
|
"repo/main.rs",
|
||||||
|
"Review this Rust code for potential bugs, unsafe patterns, \
|
||||||
|
and suggest improvements following best practices",
|
||||||
|
None,
|
||||||
|
10 // Top 10 chunks relevantes
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
println!("Code Review:\n{}", review.text);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Documentación Q&A
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Cargar documentación
|
||||||
|
let docs = std::fs::read_to_string("docs/README.md")?;
|
||||||
|
engine.load_document("docs", &docs, None).await?;
|
||||||
|
|
||||||
|
// Query usuario
|
||||||
|
let question = "How do I configure authentication?";
|
||||||
|
let relevant_chunks = engine.query("docs", question, None, 5).await?;
|
||||||
|
|
||||||
|
// Respuesta del LLM basada en docs
|
||||||
|
let answer = engine.dispatch_subtask(
|
||||||
|
"docs",
|
||||||
|
&format!("Answer this question based on the documentation: {}", question),
|
||||||
|
None,
|
||||||
|
5
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
println!("Answer: {}", answer.text);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Log Analysis
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Cargar logs (grandes volúmenes)
|
||||||
|
let logs = std::fs::read_to_string("/var/log/app.log")?;
|
||||||
|
let chunks = engine.load_document(
|
||||||
|
"logs/app",
|
||||||
|
&logs,
|
||||||
|
Some(ChunkingConfig {
|
||||||
|
strategy: ChunkingStrategy::Fixed,
|
||||||
|
chunk_size: 500, // Logs más pequeños
|
||||||
|
overlap: 50,
|
||||||
|
})
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
// Buscar errores
|
||||||
|
let errors = engine.query(
|
||||||
|
"logs/app",
|
||||||
|
"ERROR FATAL exception crash",
|
||||||
|
None,
|
||||||
|
20
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
// Análisis de root cause
|
||||||
|
let analysis = engine.dispatch_subtask(
|
||||||
|
"logs/app",
|
||||||
|
"Analyze these error logs and identify the root cause. \
|
||||||
|
Suggest fixes and preventive measures.",
|
||||||
|
None,
|
||||||
|
20
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
println!("Root Cause Analysis:\n{}", analysis.text);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Knowledge Base Building
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Cargar múltiples documentos
|
||||||
|
let docs = vec![
|
||||||
|
("guide1.md", std::fs::read_to_string("docs/guide1.md")?),
|
||||||
|
("guide2.md", std::fs::read_to_string("docs/guide2.md")?),
|
||||||
|
("api.md", std::fs::read_to_string("docs/api.md")?),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (id, content) in docs {
|
||||||
|
engine.load_document(id, &content, None).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query cross-document
|
||||||
|
let results = engine.query(
|
||||||
|
"guide1.md", // Busca en este doc primero
|
||||||
|
"authentication setup",
|
||||||
|
None,
|
||||||
|
5
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
// También buscar en otros docs
|
||||||
|
let all_results = futures::future::join_all(
|
||||||
|
["guide1.md", "guide2.md", "api.md"]
|
||||||
|
.iter()
|
||||||
|
.map(|doc_id| engine.query(doc_id, "authentication", None, 3))
|
||||||
|
).await;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adaptación
|
||||||
|
|
||||||
|
### Tuning de Performance
|
||||||
|
|
||||||
|
#### 1. Chunk Size Optimization
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Para documentos técnicos densos
|
||||||
|
ChunkingConfig {
|
||||||
|
strategy: ChunkingStrategy::Semantic,
|
||||||
|
chunk_size: 2000, // Chunks grandes = más contexto
|
||||||
|
overlap: 400, // Overlap mayor para continuidad
|
||||||
|
}
|
||||||
|
|
||||||
|
// Para búsqueda precisa
|
||||||
|
ChunkingConfig {
|
||||||
|
strategy: ChunkingStrategy::Fixed,
|
||||||
|
chunk_size: 500, // Chunks pequeños = precisión
|
||||||
|
overlap: 50, // Overlap menor = más chunks únicos
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Regla general:**
|
||||||
|
- Chunks grandes (1500-2000): Más contexto, menos chunks, búsqueda más lenta
|
||||||
|
- Chunks medianos (1000-1500): Balance óptimo
|
||||||
|
- Chunks pequeños (500-1000): Precisión alta, más chunks, más tokens
|
||||||
|
|
||||||
|
#### 2. Embedding Provider Selection
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use vapora_rlm::embeddings::EmbeddingConfig;
|
||||||
|
|
||||||
|
// Desarrollo local (gratis)
|
||||||
|
let config = RLMEngineConfig {
|
||||||
|
embedding: Some(EmbeddingConfig::ollama("llama3.2")),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Producción (mejor calidad)
|
||||||
|
let config = RLMEngineConfig {
|
||||||
|
embedding: Some(EmbeddingConfig::openai_large()), // 3072 dims
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Balance costo/calidad
|
||||||
|
let config = RLMEngineConfig {
|
||||||
|
embedding: Some(EmbeddingConfig::openai_small()), // 1536 dims
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Query Optimization
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Búsqueda amplia (exploratoria)
|
||||||
|
let results = engine.query(doc_id, query, None, 20).await?;
|
||||||
|
|
||||||
|
// Búsqueda precisa (top results)
|
||||||
|
let results = engine.query(doc_id, query, None, 3).await?;
|
||||||
|
|
||||||
|
// Con embedding personalizado
|
||||||
|
let embedding = embedding_generator.embed(query).await?;
|
||||||
|
let results = engine.query(doc_id, query, Some(&embedding), 5).await?;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Chunking Strategy
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use vapora_rlm::chunking::{Chunker, ChunkResult};
|
||||||
|
|
||||||
|
// Implementa tu propia estrategia
|
||||||
|
pub struct CustomChunker {
|
||||||
|
chunk_size: usize,
|
||||||
|
// ... custom logic
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Chunker for CustomChunker {
|
||||||
|
fn chunk(&self, text: &str) -> Result<Vec<ChunkResult>, ChunkingError> {
|
||||||
|
// Tu lógica de chunking
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Aggregation Strategy
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use vapora_rlm::dispatch::{DispatchConfig, AggregationStrategy};
|
||||||
|
|
||||||
|
let config = DispatchConfig {
|
||||||
|
include_content: true,
|
||||||
|
include_metadata: false,
|
||||||
|
max_chunks_per_dispatch: 10,
|
||||||
|
aggregation: AggregationStrategy::MajorityVote, // Para clasificación
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Problem: Query returns 0 results
|
||||||
|
|
||||||
|
**Diagnóstico:**
|
||||||
|
```rust
|
||||||
|
// 1. Verificar chunks cargados
|
||||||
|
let stats = bm25_index.stats();
|
||||||
|
println!("BM25 docs: {}", stats.num_docs);
|
||||||
|
|
||||||
|
// 2. Verificar storage
|
||||||
|
let chunks = storage.get_chunks(doc_id).await?;
|
||||||
|
println!("Storage chunks: {}", chunks.len());
|
||||||
|
|
||||||
|
// 3. Test BM25 directo
|
||||||
|
let bm25_results = bm25_index.search(query, 10)?;
|
||||||
|
println!("BM25 results: {}", bm25_results.len());
|
||||||
|
```
|
||||||
|
|
||||||
|
**Soluciones:**
|
||||||
|
- Asegurar que `load_document()` completó exitosamente
|
||||||
|
- Verificar que el query matchea contenido del documento
|
||||||
|
- Aumentar límite de resultados (`limit`)
|
||||||
|
- Usar keywords más generales
|
||||||
|
|
||||||
|
### Problem: Slow load performance
|
||||||
|
|
||||||
|
**Diagnóstico:**
|
||||||
|
```rust
|
||||||
|
let start = Instant::now();
|
||||||
|
let chunks = engine.load_document(doc_id, content, None).await?;
|
||||||
|
println!("Load time: {:?}", start.elapsed());
|
||||||
|
println!("Chunks created: {}", chunks);
|
||||||
|
println!("Time per chunk: {:?}", start.elapsed() / chunks as u32);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimizaciones:**
|
||||||
|
- Deshabilitar embeddings temporalmente: `embedding: None`
|
||||||
|
- Aumentar chunk size (menos chunks)
|
||||||
|
- Usar `auto_rebuild_bm25: false` y rebuild manual
|
||||||
|
- Batch loading para múltiples documentos
|
||||||
|
|
||||||
|
### Problem: High LLM costs
|
||||||
|
|
||||||
|
**Monitoreo:**
|
||||||
|
```rust
|
||||||
|
let response = engine.dispatch_subtask(doc_id, task, None, 5).await?;
|
||||||
|
|
||||||
|
let cost = (response.total_input_tokens as f64 * 5.0 / 1_000_000.0)
|
||||||
|
+ (response.total_output_tokens as f64 * 15.0 / 1_000_000.0);
|
||||||
|
|
||||||
|
println!("Cost this call: ${:.4}", cost);
|
||||||
|
println!("Input tokens: {}", response.total_input_tokens);
|
||||||
|
println!("Output tokens: {}", response.total_output_tokens);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Reducciones:**
|
||||||
|
- Reducir `limit` en queries (menos chunks al LLM)
|
||||||
|
- Usar modelos más baratos (gpt-3.5-turbo vs gpt-4)
|
||||||
|
- Usar Ollama local para desarrollo
|
||||||
|
- Cache de resultados frecuentes
|
||||||
|
- Chunk size más grande (menos llamadas)
|
||||||
|
|
||||||
|
### Problem: SurrealDB schema errors
|
||||||
|
|
||||||
|
**Verificación:**
|
||||||
|
```bash
|
||||||
|
# Aplicar schema correcto
|
||||||
|
cd crates/vapora-rlm/tests
|
||||||
|
bash test_setup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Alternativa manual:**
|
||||||
|
```sql
|
||||||
|
-- Conectar a SurrealDB
|
||||||
|
USE NS production DB rlm;
|
||||||
|
|
||||||
|
-- Verificar tablas
|
||||||
|
INFO FOR DB;
|
||||||
|
|
||||||
|
-- Limpiar si necesario
|
||||||
|
REMOVE TABLE rlm_chunks;
|
||||||
|
REMOVE TABLE rlm_buffers;
|
||||||
|
REMOVE TABLE rlm_executions;
|
||||||
|
|
||||||
|
-- Reaplicar schema
|
||||||
|
-- (copiar contenido de migrations/008_rlm_schema.surql)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ejemplos Completos
|
||||||
|
|
||||||
|
Ver directorio `examples/`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Local development con Ollama (gratis)
|
||||||
|
cargo run --example local_ollama
|
||||||
|
|
||||||
|
# Production con OpenAI
|
||||||
|
export OPENAI_API_KEY="sk-..."
|
||||||
|
cargo run --example production_setup
|
||||||
|
```
|
||||||
|
|
||||||
|
## Referencias
|
||||||
|
|
||||||
|
- **ADR**: `docs/architecture/decisions/008-recursive-language-models-integration.md`
|
||||||
|
- **Production Guide**: `crates/vapora-rlm/PRODUCTION.md`
|
||||||
|
- **API Docs**: `cargo doc --open -p vapora-rlm`
|
||||||
|
- **Tests**: `crates/vapora-rlm/tests/`
|
||||||
|
|
||||||
|
## Siguiente Paso
|
||||||
|
|
||||||
|
1. ✅ Ejecuta ejemplo local: `cargo run --example local_ollama`
|
||||||
|
2. ✅ Lee el ADR para decisiones arquitecturales
|
||||||
|
3. ✅ Revisa tests para ejemplos de uso: `tests/e2e_integration.rs`
|
||||||
|
4. ✅ Consulta PRODUCTION.md para deployment
|
||||||
30
migrations/008_rlm_schema.surql
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
-- Migration 008: RLM Schema
|
||||||
|
-- Creates tables for Recursive Language Models (RLM) integration
|
||||||
|
-- Provides chunking, buffering, and execution history storage
|
||||||
|
|
||||||
|
-- Use test namespace and database
|
||||||
|
USE NS test_rlm_e2e DB test_rlm_e2e;
|
||||||
|
|
||||||
|
-- RLM Chunks table (from documents)
|
||||||
|
-- Note: Using SCHEMALESS instead of SCHEMAFULL because:
|
||||||
|
-- 1. SurrealDB auto-generates `id` field for all records
|
||||||
|
-- 2. Explicit `id` field definition in SCHEMAFULL causes conflicts with CREATE queries
|
||||||
|
-- 3. SCHEMALESS provides flexibility while still allowing indexes
|
||||||
|
DEFINE TABLE rlm_chunks SCHEMALESS;
|
||||||
|
|
||||||
|
-- Indexes for efficient queries (work with SCHEMALESS tables)
|
||||||
|
DEFINE INDEX idx_rlm_chunks_chunk_id ON TABLE rlm_chunks COLUMNS chunk_id UNIQUE;
|
||||||
|
DEFINE INDEX idx_rlm_chunks_doc_id ON TABLE rlm_chunks COLUMNS doc_id;
|
||||||
|
|
||||||
|
-- RLM Buffers table (pass-by-reference for large contexts)
|
||||||
|
DEFINE TABLE rlm_buffers SCHEMALESS;
|
||||||
|
|
||||||
|
-- Indexes for buffers
|
||||||
|
DEFINE INDEX idx_rlm_buffers_buffer_id ON TABLE rlm_buffers COLUMNS buffer_id UNIQUE;
|
||||||
|
|
||||||
|
-- RLM Execution History table (for learning)
|
||||||
|
DEFINE TABLE rlm_executions SCHEMALESS;
|
||||||
|
|
||||||
|
-- Indexes for execution history
|
||||||
|
DEFINE INDEX idx_rlm_executions_execution_id ON TABLE rlm_executions COLUMNS execution_id UNIQUE;
|
||||||
|
DEFINE INDEX idx_rlm_executions_doc_id ON TABLE rlm_executions COLUMNS doc_id;
|
||||||