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;
|
||||