docs(readme): animate pool + combo ASCII blocks as SMIL SVG diagrams (#7626)

* docs(readme): animate pool + combo blocks as SMIL SVG diagrams

Replace the two remaining ASCII blocks in the README with hand-authored
animated SVGs (16s loops, SMIL only — play inside GitHub's <img> sandbox,
DESIGN_SYSTEM.md palette), following the tier-cascade.svg pattern:

- pool-fair-share.svg — key pool "team-codex" fair-share quota: weights
  50/30/20, generous mode lending idle shares, 50% threshold crossing,
  strict mode holding each key to its cap (verbatim README copy).
- combo-always-on.svg — combo "always-on" priority strategy: 4 fallback
  layers with coral hand-off on failure and an uptime bar that never
  drops (zero downtime).

Both blocks keep their full flow text in the img alt. Registered in
docs/diagrams/README.md (hand-authored table).

* docs(changelog): add fragment for #7626 (pool + combo SVG diagrams)
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-17 16:46:24 -03:00
committed by GitHub
parent a5714f35a5
commit 89025c12f1
5 changed files with 439 additions and 16 deletions

View File

@@ -255,14 +255,7 @@ All **18** strategies — mix & match per combo step:
| 🚦 **Policy** | `hard` (block over share) · `soft` (deprioritize) · `burst` (use idle headroom) |
| 🧱 **Cap** | absolute ceiling per key, independent of mode |
```
Pool "team-codex" · 1 Codex Pro account · 3 keys · 5-hour window
├─ alice weight 50 ██████████░░░░░░░░░░ ≤ 50% of the shared 5h quota
├─ bob weight 30 ██████░░░░░░░░░░░░░░ ≤ 30%
└─ ci-bot weight 20 ████░░░░░░░░░░░░░░░░ ≤ 20%
Generous mode (<50% pool used) → idle shares are lent out
Strict mode (≥50% pool used) → each key held to its fair share
```
<img src="./docs/diagrams/pool-fair-share.svg" width="100%" alt="OmniRoute key pool 'team-codex': one Codex Pro account shared by 3 keys over a 5-hour window. alice weight 50 (up to 50% of the shared 5h quota), bob weight 30, ci-bot weight 20. In generous mode (under 50% pool used) idle shares are lent out; once the pool crosses 50% strict mode holds each key to its fair share."/>
<sub>Enforced in the hot path **before** the request leaves OmniRoute, with per-(key, model) caps + session stickiness for prompt-cache integrity (now with a per-combo / global disable toggle). 📖 [Quota Sharing Engine](docs/routing/QUOTA_SHARE.md)</sub>
@@ -276,14 +269,7 @@ Strict mode (≥50% pool used) → each key held to its fair share
| 💤 **Connection cooldown** | one account / key | Skips a rate-limited key while other keys keep serving |
| 🎯 **Model lockout** | provider + model | Quarantines just one quota-limited model, not the whole connection |
```
Combo: "always-on" Strategy: priority
1. cc/claude-opus-4-7 ← subscription (use it fully)
2. cx/gpt-5.5 ← second subscription
3. glm/glm-5.1 ← cheap backup ($0.5/1M)
4. kr/claude-sonnet-4.5 ← FREE, unlimited (never fails)
Result: 4 layers of fallback = zero downtime
```
<img src="./docs/diagrams/combo-always-on.svg" width="100%" alt="OmniRoute combo 'always-on' with priority strategy: requests go to 1. cc/claude-opus-4-7 (subscription, use it fully); on failure fall through to 2. cx/gpt-5.5 (second subscription), then 3. glm/glm-5.1 (cheap backup at $0.5/1M), then 4. kr/claude-sonnet-4.5 (free, unlimited, never fails). Result: 4 layers of fallback = zero downtime."/>
<sub>📖 [Auto-Combo Engine](docs/routing/AUTO-COMBO.md) · [Resilience Guide](docs/architecture/RESILIENCE_GUIDE.md)</sub>

View File

@@ -0,0 +1 @@
- **README animated diagrams** (`docs/diagrams/pool-fair-share.svg`, `docs/diagrams/combo-always-on.svg`): the last two ASCII blocks in the root README — the `"team-codex"` key-pool fair-share example and the `"always-on"` priority combo — are now hand-authored SMIL SVG animations (16s loops, DESIGN_SYSTEM.md palette, GitHub `<img>`-sandbox safe), completing the set started by tier-cascade.svg (#7615). Full block copy preserved verbatim in the `img` alt text; both registered in `docs/diagrams/README.md`.

View File

@@ -30,6 +30,8 @@ inside GitHub's `<img>` sandbox:
| File | Used in | Notes |
| ---------------------------------------- | ---------------- | ---------------------------------------------------------------------------- |
| [tier-cascade.svg](./tier-cascade.svg) | README.md (root) | Animated 4-tier auto-fallback cascade (16s loop, 4 acts). Edit the SVG directly — there is no `.mmd` source. |
| [pool-fair-share.svg](./pool-fair-share.svg) | README.md (root) | Animated key-pool fair-share quota (generous → strict, 16s loop). Edit the SVG directly — there is no `.mmd` source. |
| [combo-always-on.svg](./combo-always-on.svg) | README.md (root) | Animated priority-combo fallback (4 layers, 16s loop). Edit the SVG directly — there is no `.mmd` source. |
## How to update

View File

@@ -0,0 +1,230 @@
<svg viewBox="0 0 1200 650" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="OmniRoute combo 'always-on' with priority strategy: requests go to 1. cc/claude-opus-4-7 (subscription, use it fully); on failure fall through to 2. cx/gpt-5.5 (second subscription), then 3. glm/glm-5.1 (cheap backup at $0.5/1M), then 4. kr/claude-sonnet-4.5 (free, unlimited, never fails). Result: 4 layers of fallback, zero downtime.">
<defs>
<radialGradient id="hubGlowC" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#e54d5e" stop-opacity="0.5"/>
<stop offset="100%" stop-color="#e54d5e" stop-opacity="0"/>
</radialGradient>
<radialGradient id="bgGlowC" cx="42%" cy="35%" r="60%">
<stop offset="0%" stop-color="#6366f1" stop-opacity="0.12"/>
<stop offset="60%" stop-color="#6366f1" stop-opacity="0.04"/>
<stop offset="100%" stop-color="#6366f1" stop-opacity="0"/>
</radialGradient>
<linearGradient id="gradBrandC" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#e54d5e"/>
<stop offset="100%" stop-color="#a855f7"/>
</linearGradient>
<pattern id="gridPaperC" width="32" height="32" patternUnits="userSpaceOnUse">
<path d="M 32 0 L 0 0 0 32" fill="none" stroke="#ffffff" stroke-opacity="0.06" stroke-width="1"/>
</pattern>
<!-- request feed into the combo -->
<path id="pInC" d="M 26,295 L 86,295"/>
<!-- combo → each priority card -->
<path id="pF1" d="M 420,270 C 472,270 468,128 520,128"/>
<path id="pF2" d="M 420,290 C 472,290 468,246 520,246"/>
<path id="pF3" d="M 420,310 C 472,310 468,364 520,364"/>
<path id="pF4" d="M 420,330 C 472,330 468,482 520,482"/>
<!-- fall-through drops between cards -->
<path id="pD1" d="M 534,150 L 534,246"/>
<path id="pD2" d="M 534,268 L 534,364"/>
<path id="pD3" d="M 534,386 L 534,482"/>
</defs>
<rect width="1200" height="650" fill="#0b0e14"/>
<rect width="1200" height="650" fill="url(#gridPaperC)"/>
<rect width="1200" height="650" fill="url(#bgGlowC)"/>
<!-- ═══ Combo card ═══ -->
<rect x="90" y="210" width="330" height="170" rx="14" fill="#161b22" stroke="#8b5cf6" stroke-width="1.2" stroke-opacity="0.45"/>
<g transform="translate(112, 254)">
<circle cx="42" cy="42" r="34" fill="none" stroke="#e54d5e" stroke-width="1" opacity="0.35" stroke-dasharray="3 7">
<animateTransform attributeName="transform" type="rotate" from="0 42 42" to="360 42 42" dur="30s" repeatCount="indefinite"/>
</circle>
<circle cx="42" cy="42" r="24" fill="url(#hubGlowC)">
<animate attributeName="r" values="22;30;22" dur="3.2s" repeatCount="indefinite"/>
</circle>
<g stroke="#e54d5e" stroke-width="5" stroke-linecap="round" fill="none">
<line x1="22" y1="42" x2="38" y2="42"/>
<path d="M 39 42 C 52 42, 54 26, 66 24"/>
<path d="M 39 42 C 54 42, 56 42, 68 42"/>
<path d="M 39 42 C 52 42, 54 58, 66 60"/>
</g>
<circle cx="39" cy="42" r="5" fill="#f7f6fc">
<animate attributeName="opacity" values="1;0.7;1" dur="1.8s" repeatCount="indefinite"/>
</circle>
</g>
<text x="212" y="252" font-family="Consolas, 'Courier New', monospace" font-size="10" letter-spacing="2.5" font-weight="700" fill="#a78bfa">COMBO</text>
<text x="212" y="278" font-family="Consolas, 'Courier New', monospace" font-size="17" font-weight="700" fill="url(#gradBrandC)">"always-on"</text>
<text x="212" y="304" font-family="Consolas, 'Courier New', monospace" font-size="11.5" fill="#a1a1aa">Strategy: <tspan fill="#8b5cf6" font-weight="700">priority</tspan></text>
<text x="212" y="326" font-family="Consolas, 'Courier New', monospace" font-size="10.5" fill="#71717a">try 1 first &#183; fall through</text>
<text x="212" y="344" font-family="Consolas, 'Courier New', monospace" font-size="10.5" fill="#71717a">on failure</text>
<!-- incoming requests -->
<text x="26" y="280" font-family="Consolas, 'Courier New', monospace" font-size="9.5" letter-spacing="1.5" fill="#71717a">REQUESTS</text>
<use href="#pInC" stroke="#6366f1" stroke-width="1.2" stroke-dasharray="3 5" opacity="0.4"/>
<!-- fan-out topology (always faintly visible) -->
<g stroke="#6366f1" stroke-width="1.2" fill="none" stroke-dasharray="3 5" opacity="0.35">
<use href="#pF1"/><use href="#pF2"/><use href="#pF3"/><use href="#pF4"/>
</g>
<!-- fall-through rails -->
<g stroke="#6366f1" stroke-width="1" fill="none" stroke-dasharray="2 4" opacity="0.25">
<use href="#pD1"/><use href="#pD2"/><use href="#pD3"/>
</g>
<!-- ═══ Priority cards ═══ -->
<!-- 1 · cc/claude-opus-4-7 -->
<g transform="translate(520, 80)">
<rect width="560" height="96" rx="14" fill="#161b22" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
<rect width="560" height="96" rx="14" fill="none" stroke="#22c55e" stroke-width="1.4" stroke-opacity="0.9">
<animate attributeName="stroke-opacity" values="0.9;0.9;0;0;0.9" keyTimes="0;0.24;0.27;0.985;1" dur="16s" repeatCount="indefinite"/>
</rect>
<text x="30" y="56" font-family="Consolas, 'Courier New', monospace" font-size="20" font-weight="800" fill="#71717a">1</text>
<text x="70" y="44" font-family="Consolas, 'Courier New', monospace" font-size="15" font-weight="700" fill="#F7F6FC"><tspan fill="#8b5cf6">cc/</tspan>claude-opus-4-7</text>
<text x="70" y="68" font-family="Consolas, 'Courier New', monospace" font-size="10.5" fill="#a1a1aa">subscription &#183; use it fully</text>
<circle cx="524" cy="48" r="4.5" fill="#22c55e">
<animate attributeName="fill" values="#22c55e;#22c55e;#ef4444;#ef4444;#22c55e" keyTimes="0;0.24;0.28;0.985;1" dur="16s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="1;0.45;1" dur="2s" repeatCount="indefinite"/>
</circle>
</g>
<!-- 2 · cx/gpt-5.5 -->
<g transform="translate(520, 198)">
<rect width="560" height="96" rx="14" fill="#161b22" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
<rect width="560" height="96" rx="14" fill="none" stroke="#22c55e" stroke-width="1.4" stroke-opacity="0">
<animate attributeName="stroke-opacity" values="0;0;0.9;0.9;0;0" keyTimes="0;0.28;0.31;0.48;0.51;1" dur="16s" repeatCount="indefinite"/>
</rect>
<text x="30" y="56" font-family="Consolas, 'Courier New', monospace" font-size="20" font-weight="800" fill="#71717a">2</text>
<text x="70" y="44" font-family="Consolas, 'Courier New', monospace" font-size="15" font-weight="700" fill="#F7F6FC"><tspan fill="#8b5cf6">cx/</tspan>gpt-5.5</text>
<text x="70" y="68" font-family="Consolas, 'Courier New', monospace" font-size="10.5" fill="#a1a1aa">second subscription</text>
<circle cx="524" cy="48" r="4.5" fill="#71717a">
<animate attributeName="fill" values="#71717a;#71717a;#22c55e;#22c55e;#ef4444;#ef4444;#71717a" keyTimes="0;0.28;0.31;0.48;0.52;0.985;1" dur="16s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="1;0.45;1" dur="2s" repeatCount="indefinite"/>
</circle>
</g>
<!-- 3 · glm/glm-5.1 -->
<g transform="translate(520, 316)">
<rect width="560" height="96" rx="14" fill="#161b22" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
<rect width="560" height="96" rx="14" fill="none" stroke="#22c55e" stroke-width="1.4" stroke-opacity="0">
<animate attributeName="stroke-opacity" values="0;0;0.9;0.9;0;0" keyTimes="0;0.53;0.56;0.73;0.76;1" dur="16s" repeatCount="indefinite"/>
</rect>
<text x="30" y="56" font-family="Consolas, 'Courier New', monospace" font-size="20" font-weight="800" fill="#71717a">3</text>
<text x="70" y="44" font-family="Consolas, 'Courier New', monospace" font-size="15" font-weight="700" fill="#F7F6FC"><tspan fill="#8b5cf6">glm/</tspan>glm-5.1</text>
<text x="70" y="68" font-family="Consolas, 'Courier New', monospace" font-size="10.5" fill="#a1a1aa">cheap backup &#183; <tspan fill="#f59e0b">$0.5/1M</tspan></text>
<circle cx="524" cy="48" r="4.5" fill="#71717a">
<animate attributeName="fill" values="#71717a;#71717a;#22c55e;#22c55e;#ef4444;#ef4444;#71717a" keyTimes="0;0.53;0.56;0.73;0.77;0.985;1" dur="16s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="1;0.45;1" dur="2s" repeatCount="indefinite"/>
</circle>
</g>
<!-- 4 · kr/claude-sonnet-4.5 -->
<g transform="translate(520, 434)">
<rect width="560" height="96" rx="14" fill="#161b22" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
<rect width="560" height="96" rx="14" fill="none" stroke="#22c55e" stroke-width="1.4" stroke-opacity="0">
<animate attributeName="stroke-opacity" values="0;0;0.9;0.9;0" keyTimes="0;0.78;0.81;0.985;1" dur="16s" repeatCount="indefinite"/>
</rect>
<text x="30" y="56" font-family="Consolas, 'Courier New', monospace" font-size="20" font-weight="800" fill="#71717a">4</text>
<text x="70" y="44" font-family="Consolas, 'Courier New', monospace" font-size="15" font-weight="700" fill="#F7F6FC"><tspan fill="#8b5cf6">kr/</tspan>claude-sonnet-4.5</text>
<text x="70" y="68" font-family="Consolas, 'Courier New', monospace" font-size="10.5" fill="#a1a1aa"><tspan fill="#22c55e" font-weight="700">FREE</tspan> &#183; unlimited &#183; never fails</text>
<circle cx="524" cy="48" r="4.5" fill="#71717a">
<animate attributeName="fill" values="#71717a;#71717a;#22c55e;#22c55e;#71717a" keyTimes="0;0.78;0.81;0.985;1" dur="16s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="1;0.45;1" dur="2s" repeatCount="indefinite"/>
</circle>
</g>
<!-- ═══ Traffic dots (act-windowed) ═══ -->
<!-- incoming feed, steady except at the loop seam -->
<g fill="#a78bfa">
<animate attributeName="opacity" values="1;1;0;0;1" keyTimes="0;0.945;0.965;0.99;1" dur="16s" repeatCount="indefinite"/>
<circle r="3.2">
<animateMotion dur="1.2s" repeatCount="indefinite" begin="0s"><mpath href="#pInC"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.2s" begin="0s" repeatCount="indefinite"/>
</circle>
<circle r="3.2">
<animateMotion dur="1.2s" repeatCount="indefinite" begin="0.6s"><mpath href="#pInC"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.2s" begin="0.6s" repeatCount="indefinite"/>
</circle>
</g>
<!-- act 1: combo → priority 1 -->
<g fill="#8b5cf6">
<animate attributeName="opacity" values="1;1;0;0" keyTimes="0;0.235;0.245;1" dur="16s" repeatCount="indefinite"/>
<circle r="3.4">
<animateMotion dur="1.4s" repeatCount="indefinite" begin="0s"><mpath href="#pF1"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.4s" begin="0s" repeatCount="indefinite"/>
</circle>
<circle r="3.4">
<animateMotion dur="1.4s" repeatCount="indefinite" begin="0.7s"><mpath href="#pF1"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.4s" begin="0.7s" repeatCount="indefinite"/>
</circle>
</g>
<!-- act 2: combo → priority 2 -->
<g fill="#8b5cf6">
<animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.28;0.30;0.475;0.485;1" dur="16s" repeatCount="indefinite"/>
<circle r="3.4">
<animateMotion dur="1.4s" repeatCount="indefinite" begin="0s"><mpath href="#pF2"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.4s" begin="0s" repeatCount="indefinite"/>
</circle>
<circle r="3.4">
<animateMotion dur="1.4s" repeatCount="indefinite" begin="0.7s"><mpath href="#pF2"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.4s" begin="0.7s" repeatCount="indefinite"/>
</circle>
</g>
<!-- act 3: combo → priority 3 -->
<g fill="#8b5cf6">
<animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.53;0.55;0.725;0.735;1" dur="16s" repeatCount="indefinite"/>
<circle r="3.4">
<animateMotion dur="1.4s" repeatCount="indefinite" begin="0s"><mpath href="#pF3"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.4s" begin="0s" repeatCount="indefinite"/>
</circle>
<circle r="3.4">
<animateMotion dur="1.4s" repeatCount="indefinite" begin="0.7s"><mpath href="#pF3"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.4s" begin="0.7s" repeatCount="indefinite"/>
</circle>
</g>
<!-- act 4: combo → priority 4 -->
<g fill="#8b5cf6">
<animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.78;0.80;0.945;0.955;1" dur="16s" repeatCount="indefinite"/>
<circle r="3.4">
<animateMotion dur="1.4s" repeatCount="indefinite" begin="0s"><mpath href="#pF4"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.4s" begin="0s" repeatCount="indefinite"/>
</circle>
<circle r="3.4">
<animateMotion dur="1.4s" repeatCount="indefinite" begin="0.7s"><mpath href="#pF4"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.4s" begin="0.7s" repeatCount="indefinite"/>
</circle>
</g>
<!-- ═══ Fall-through hand-offs (brand coral) ═══ -->
<g fill="#e54d5e">
<circle r="4">
<animateMotion dur="16s" repeatCount="indefinite" keyPoints="0;0;1;1" keyTimes="0;0.24;0.275;1" calcMode="linear"><mpath href="#pD1"/></animateMotion>
<animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.24;0.245;0.27;0.28;1" dur="16s" repeatCount="indefinite"/>
</circle>
<circle r="4">
<animateMotion dur="16s" repeatCount="indefinite" keyPoints="0;0;1;1" keyTimes="0;0.485;0.52;1" calcMode="linear"><mpath href="#pD2"/></animateMotion>
<animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.485;0.49;0.515;0.525;1" dur="16s" repeatCount="indefinite"/>
</circle>
<circle r="4">
<animateMotion dur="16s" repeatCount="indefinite" keyPoints="0;0;1;1" keyTimes="0;0.735;0.77;1" calcMode="linear"><mpath href="#pD3"/></animateMotion>
<animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.735;0.74;0.765;0.775;1" dur="16s" repeatCount="indefinite"/>
</circle>
</g>
<!-- transition labels -->
<text x="552" y="196" font-family="Consolas, 'Courier New', monospace" font-size="9.5" fill="#ef4444" opacity="0">
<animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.235;0.25;0.30;0.32;1" dur="16s" repeatCount="indefinite"/>fails &#8594; next</text>
<text x="552" y="314" font-family="Consolas, 'Courier New', monospace" font-size="9.5" fill="#ef4444" opacity="0">
<animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.48;0.495;0.545;0.565;1" dur="16s" repeatCount="indefinite"/>fails &#8594; next</text>
<text x="552" y="432" font-family="Consolas, 'Courier New', monospace" font-size="9.5" fill="#ef4444" opacity="0">
<animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.73;0.745;0.795;0.815;1" dur="16s" repeatCount="indefinite"/>fails &#8594; next</text>
<!-- ═══ Footer: the uptime bar that never drops ═══ -->
<text x="90" y="588" font-family="Consolas, 'Courier New', monospace" font-size="9.5" letter-spacing="2" font-weight="700" fill="#71717a">UPTIME</text>
<rect x="90" y="596" width="1020" height="6" rx="3" fill="#22c55e" opacity="0.8">
<animate attributeName="opacity" values="0.8;1;0.8" dur="3s" repeatCount="indefinite"/>
</rect>
<g transform="translate(986, 566)">
<rect width="124" height="24" rx="12" fill="#161b22" stroke="#22c55e" stroke-width="1" stroke-opacity="0.6"/>
<circle cx="16" cy="12" r="3" fill="#22c55e">
<animate attributeName="opacity" values="1;0.35;1" dur="1.6s" repeatCount="indefinite"/>
</circle>
<text x="70" y="16" text-anchor="middle" font-family="Consolas, 'Courier New', monospace" font-size="9.5" letter-spacing="2" font-weight="700" fill="#22c55e">ALWAYS ON</text>
</g>
<text x="600" y="634" text-anchor="middle" font-family="Consolas, 'Courier New', monospace" font-size="12.5" fill="#a1a1aa">Result: 4 layers of fallback = <tspan fill="#22c55e" font-weight="700">zero downtime</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,204 @@
<svg viewBox="0 0 1200 650" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="OmniRoute key pool 'team-codex': one Codex Pro account shared by 3 keys over a 5-hour window. alice weight 50, bob weight 30, ci-bot weight 20. In generous mode (under 50% pool used) idle shares are lent out; once the pool crosses 50% strict mode holds each key to its fair share.">
<defs>
<radialGradient id="bgGlowP" cx="50%" cy="30%" r="60%">
<stop offset="0%" stop-color="#6366f1" stop-opacity="0.12"/>
<stop offset="60%" stop-color="#6366f1" stop-opacity="0.04"/>
<stop offset="100%" stop-color="#6366f1" stop-opacity="0"/>
</radialGradient>
<linearGradient id="gradBrandP" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#e54d5e"/>
<stop offset="100%" stop-color="#a855f7"/>
</linearGradient>
<pattern id="gridPaperP" width="32" height="32" patternUnits="userSpaceOnUse">
<path d="M 32 0 L 0 0 0 32" fill="none" stroke="#ffffff" stroke-opacity="0.06" stroke-width="1"/>
</pattern>
<!-- request feed paths, one per lane -->
<path id="pReqA" d="M 236,192 L 352,192"/>
<path id="pReqB" d="M 236,324 L 352,324"/>
<path id="pReqC" d="M 236,456 L 352,456"/>
<!-- rejected request: travels to ci-bot's cap line and stops -->
<path id="pRejC" d="M 236,456 L 414,456"/>
<!-- idle share of bob lent down to ci-bot's borrowed segment -->
<path id="pLend" d="M 430,324 C 430,392 446,390 446,440"/>
</defs>
<rect width="1200" height="650" fill="#0b0e14"/>
<rect width="1200" height="650" fill="url(#gridPaperP)"/>
<rect width="1200" height="650" fill="url(#bgGlowP)"/>
<!-- ═══ Pool header card ═══ -->
<rect x="90" y="28" width="1020" height="84" rx="14" fill="#161b22" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
<text x="120" y="60" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="19" font-weight="800" fill="#F7F6FC">Pool <tspan font-family="Consolas, 'Courier New', monospace" fill="url(#gradBrandP)">"team-codex"</tspan></text>
<text x="120" y="84" font-family="Consolas, 'Courier New', monospace" font-size="11.5" fill="#a1a1aa">1 Codex Pro account · <tspan fill="#8b5cf6">3 keys</tspan> · 5-hour window</text>
<!-- pool usage meter -->
<text x="520" y="50" font-family="Consolas, 'Courier New', monospace" font-size="9.5" letter-spacing="2" font-weight="700" fill="#71717a">POOL USED</text>
<rect x="520" y="58" width="280" height="14" rx="7" fill="#1c2230" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
<rect x="521" y="59" height="12" rx="6" width="0" fill="#22c55e">
<animate attributeName="width" values="0;92;129;176;190;190;0" keyTimes="0;0.25;0.50;0.59;0.80;0.965;1" dur="16s" repeatCount="indefinite"/>
<animate attributeName="fill" values="#22c55e;#22c55e;#f59e0b;#f59e0b" keyTimes="0;0.52;0.55;1" dur="16s" repeatCount="indefinite"/>
</rect>
<!-- 50% threshold mark -->
<line x1="660" y1="52" x2="660" y2="78" stroke="#a1a1aa" stroke-width="1.2" stroke-dasharray="2 2" stroke-opacity="0.6">
<animate attributeName="stroke" values="#a1a1aa;#a1a1aa;#f59e0b;#f59e0b;#a1a1aa;#a1a1aa" keyTimes="0;0.52;0.53;0.60;0.63;1" dur="16s" repeatCount="indefinite"/>
<animate attributeName="stroke-opacity" values="0.6;0.6;1;1;0.6;0.6" keyTimes="0;0.52;0.53;0.60;0.63;1" dur="16s" repeatCount="indefinite"/>
</line>
<text x="660" y="90" text-anchor="middle" font-family="Consolas, 'Courier New', monospace" font-size="9" fill="#71717a">50%</text>
<text x="520" y="90" font-family="Consolas, 'Courier New', monospace" font-size="9" fill="#71717a">0</text>
<text x="800" y="90" text-anchor="end" font-family="Consolas, 'Courier New', monospace" font-size="9" fill="#71717a">100%</text>
<!-- mode pills (swap at the 50% crossing) -->
<g>
<animate attributeName="opacity" values="1;1;0;0" keyTimes="0;0.52;0.545;1" dur="16s" repeatCount="indefinite"/>
<rect x="852" y="52" width="228" height="30" rx="15" fill="#161b22" stroke="#22c55e" stroke-width="1" stroke-opacity="0.6"/>
<circle cx="872" cy="67" r="3.5" fill="#22c55e">
<animate attributeName="opacity" values="1;0.35;1" dur="1.6s" repeatCount="indefinite"/>
</circle>
<text x="886" y="71" font-family="Consolas, 'Courier New', monospace" font-size="10" letter-spacing="1.5" font-weight="700" fill="#22c55e">GENEROUS · &lt;50% USED</text>
</g>
<g opacity="0">
<animate attributeName="opacity" values="0;0;1;1" keyTimes="0;0.53;0.555;1" dur="16s" repeatCount="indefinite"/>
<rect x="852" y="52" width="228" height="30" rx="15" fill="#161b22" stroke="#f59e0b" stroke-width="1" stroke-opacity="0.7"/>
<circle cx="872" cy="67" r="3.5" fill="#f59e0b">
<animate attributeName="opacity" values="1;0.35;1" dur="1s" repeatCount="indefinite"/>
</circle>
<text x="886" y="71" font-family="Consolas, 'Courier New', monospace" font-size="10" letter-spacing="1.5" font-weight="700" fill="#f59e0b">STRICT · &#8805;50% USED</text>
</g>
<!-- ═══ Key lanes ═══ -->
<!-- lane cards -->
<rect x="90" y="140" width="1020" height="104" rx="14" fill="#161b22" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
<rect x="90" y="272" width="1020" height="104" rx="14" fill="#161b22" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
<rect x="90" y="404" width="1020" height="104" rx="14" fill="#161b22" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
<!-- key names + weights -->
<text x="124" y="188" font-family="Consolas, 'Courier New', monospace" font-size="15" font-weight="700" fill="#F7F6FC">alice</text>
<text x="124" y="208" font-family="Consolas, 'Courier New', monospace" font-size="10.5" fill="#71717a">weight 50</text>
<text x="124" y="320" font-family="Consolas, 'Courier New', monospace" font-size="15" font-weight="700" fill="#F7F6FC">bob</text>
<text x="124" y="340" font-family="Consolas, 'Courier New', monospace" font-size="10.5" fill="#71717a">weight 30</text>
<text x="124" y="452" font-family="Consolas, 'Courier New', monospace" font-size="15" font-weight="700" fill="#F7F6FC">ci-bot</text>
<text x="124" y="472" font-family="Consolas, 'Courier New', monospace" font-size="10.5" fill="#71717a">weight 20</text>
<!-- usage tracks (full track = 100% of the shared quota) -->
<rect x="310" y="183" width="560" height="18" rx="9" fill="#1c2230" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
<rect x="310" y="315" width="560" height="18" rx="9" fill="#1c2230" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
<rect x="310" y="447" width="560" height="18" rx="9" fill="#1c2230" stroke="#ffffff" stroke-opacity="0.08" stroke-width="1"/>
<!-- fair-share regions (tinted) -->
<rect x="310" y="183" width="280" height="18" rx="9" fill="#6366f1" opacity="0.10"/>
<rect x="310" y="315" width="168" height="18" rx="9" fill="#6366f1" opacity="0.10"/>
<rect x="310" y="447" width="112" height="18" rx="9" fill="#6366f1" opacity="0.10"/>
<!-- cap lines (turn amber when strict mode enforces) -->
<g stroke-width="1.6">
<line x1="590" y1="176" x2="590" y2="208" stroke="#6366f1" stroke-opacity="0.65">
<animate attributeName="stroke" values="#6366f1;#6366f1;#f59e0b;#f59e0b" keyTimes="0;0.53;0.56;1" dur="16s" repeatCount="indefinite"/>
</line>
<line x1="478" y1="308" x2="478" y2="340" stroke="#6366f1" stroke-opacity="0.65">
<animate attributeName="stroke" values="#6366f1;#6366f1;#f59e0b;#f59e0b" keyTimes="0;0.53;0.56;1" dur="16s" repeatCount="indefinite"/>
</line>
<line x1="422" y1="440" x2="422" y2="472" stroke="#6366f1" stroke-opacity="0.65">
<animate attributeName="stroke" values="#6366f1;#6366f1;#f59e0b;#f59e0b" keyTimes="0;0.53;0.56;1" dur="16s" repeatCount="indefinite"/>
</line>
</g>
<!-- right-hand share labels (verbatim from the README block) -->
<text x="890" y="196" font-family="Consolas, 'Courier New', monospace" font-size="11" fill="#a1a1aa">&#8804; 50% of the shared 5h quota</text>
<text x="890" y="328" font-family="Consolas, 'Courier New', monospace" font-size="11" fill="#a1a1aa">&#8804; 30%</text>
<text x="890" y="460" font-family="Consolas, 'Courier New', monospace" font-size="11" fill="#a1a1aa">&#8804; 20%</text>
<!-- ═══ Animated usage (seam-dip group) ═══ -->
<g>
<animate attributeName="opacity" values="1;1;0;0;1" keyTimes="0;0.94;0.965;0.99;1" dur="16s" repeatCount="indefinite"/>
<!-- usage bars -->
<rect x="311" y="184" height="16" rx="8" width="0" fill="#8b5cf6">
<animate attributeName="width" values="0;38;67;67;140;168;168;0" keyTimes="0;0.12;0.25;0.50;0.59;0.80;0.965;1" dur="16s" repeatCount="indefinite"/>
</rect>
<rect x="311" y="316" height="16" rx="8" width="0" fill="#8b5cf6">
<animate attributeName="width" values="0;19;34;34;56;56;0" keyTimes="0;0.15;0.25;0.50;0.59;0.965;1" dur="16s" repeatCount="indefinite"/>
</rect>
<rect x="311" y="448" height="16" rx="8" width="0" fill="#8b5cf6">
<animate attributeName="width" values="0;56;84;112;112;112;0" keyTimes="0;0.12;0.25;0.36;0.50;0.965;1" dur="16s" repeatCount="indefinite"/>
</rect>
<!-- ci-bot borrowed segment: grows while generous, stays (already spent) but dims under strict -->
<rect x="420" y="448" height="16" rx="8" width="0" fill="#22c55e">
<animate attributeName="width" values="0;0;47;47;47;0" keyTimes="0;0.36;0.47;0.50;0.965;1" dur="16s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="1;1;0.45;0.45" keyTimes="0;0.53;0.56;1" dur="16s" repeatCount="indefinite"/>
</rect>
<text x="444" y="440" text-anchor="middle" font-family="Consolas, 'Courier New', monospace" font-size="9.5" fill="#22c55e" opacity="0">
<animate attributeName="opacity" values="0;0;1;1;0.35;0.35;0" keyTimes="0;0.37;0.42;0.52;0.56;0.94;1" dur="16s" repeatCount="indefinite"/>lent</text>
<!-- pool meter lives with the bars so the seam resets together -->
<!-- ── request dots · alice (steady all along) ── -->
<g fill="#a78bfa">
<circle r="3.2">
<animateMotion dur="1.5s" repeatCount="indefinite" begin="0s"><mpath href="#pReqA"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.5s" begin="0s" repeatCount="indefinite"/>
</circle>
<circle r="3.2">
<animateMotion dur="1.5s" repeatCount="indefinite" begin="0.75s"><mpath href="#pReqA"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.5s" begin="0.75s" repeatCount="indefinite"/>
</circle>
</g>
<!-- ── request dots · bob (goes idle during the burst window) ── -->
<g fill="#a78bfa">
<animate attributeName="opacity" values="1;1;0;0;1;1" keyTimes="0;0.25;0.28;0.50;0.53;1" dur="16s" repeatCount="indefinite"/>
<circle r="3.2">
<animateMotion dur="2.6s" repeatCount="indefinite" begin="0.4s"><mpath href="#pReqB"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="2.6s" begin="0.4s" repeatCount="indefinite"/>
</circle>
</g>
<text x="240" y="310" font-family="Consolas, 'Courier New', monospace" font-size="9.5" fill="#71717a" opacity="0">
<animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.28;0.32;0.48;0.52;1" dur="16s" repeatCount="indefinite"/>idle</text>
<!-- ── request dots · ci-bot: normal → burst (generous) ── -->
<g fill="#a78bfa">
<animate attributeName="opacity" values="1;1;0;0" keyTimes="0;0.50;0.53;1" dur="16s" repeatCount="indefinite"/>
<circle r="3.2">
<animateMotion dur="0.8s" repeatCount="indefinite" begin="0s"><mpath href="#pReqC"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="0.8s" begin="0s" repeatCount="indefinite"/>
</circle>
<circle r="3.2">
<animateMotion dur="0.8s" repeatCount="indefinite" begin="0.4s"><mpath href="#pReqC"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="0.8s" begin="0.4s" repeatCount="indefinite"/>
</circle>
</g>
<!-- ── idle share lent: green dot dropping from bob's spare share into ci-bot's borrowed segment ── -->
<g fill="#22c55e">
<animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.36;0.38;0.48;0.50;1" dur="16s" repeatCount="indefinite"/>
<circle r="3">
<animateMotion dur="1.3s" repeatCount="indefinite"><mpath href="#pLend"/></animateMotion>
<animate attributeName="opacity" values="0;1;1;0" dur="1.3s" repeatCount="indefinite"/>
</circle>
</g>
<!-- ── strict mode: ci-bot requests held at the cap line ── -->
<g>
<animate attributeName="opacity" values="0;0;1;1;0;0" keyTimes="0;0.59;0.61;0.92;0.94;1" dur="16s" repeatCount="indefinite"/>
<circle r="3.2" fill="#a78bfa">
<animateMotion dur="2.4s" repeatCount="indefinite" keyPoints="0;0.9;1;1" keyTimes="0;0.55;0.7;1" calcMode="linear"><mpath href="#pRejC"/></animateMotion>
<animate attributeName="fill" values="#a78bfa;#a78bfa;#ef4444;#ef4444" keyTimes="0;0.6;0.7;1" dur="2.4s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="0;1;1;1;0" keyTimes="0;0.1;0.6;0.82;1" dur="2.4s" repeatCount="indefinite"/>
</circle>
<text x="422" y="434" text-anchor="middle" font-family="Consolas, 'Courier New', monospace" font-size="12" font-weight="700" fill="#ef4444" opacity="0">
<animate attributeName="opacity" values="0;0;1;0;0" keyTimes="0;0.68;0.78;0.95;1" dur="2.4s" repeatCount="indefinite"/>&#10005;</text>
</g>
</g>
<!-- ═══ Footer: the two modes, verbatim, active one highlighted ═══ -->
<circle cx="130" cy="556" r="3.5" fill="#22c55e">
<animate attributeName="opacity" values="1;1;0.25;0.25" keyTimes="0;0.52;0.56;1" dur="16s" repeatCount="indefinite"/>
</circle>
<text x="146" y="561" font-family="Consolas, 'Courier New', monospace" font-size="12.5" fill="#F7F6FC">
<animate attributeName="fill" values="#F7F6FC;#F7F6FC;#71717a;#71717a" keyTimes="0;0.52;0.56;1" dur="16s" repeatCount="indefinite"/>Generous mode (&lt;50% pool used) &#8594; idle shares are lent out</text>
<circle cx="130" cy="586" r="3.5" fill="#f59e0b" opacity="0.25">
<animate attributeName="opacity" values="0.25;0.25;1;1" keyTimes="0;0.52;0.56;1" dur="16s" repeatCount="indefinite"/>
</circle>
<text x="146" y="591" font-family="Consolas, 'Courier New', monospace" font-size="12.5" fill="#71717a">
<animate attributeName="fill" values="#71717a;#71717a;#F7F6FC;#F7F6FC" keyTimes="0;0.52;0.56;1" dur="16s" repeatCount="indefinite"/>Strict mode (&#8805;50% pool used) &#8594; each key held to its fair share</text>
<text x="600" y="622" text-anchor="middle" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="11" fill="#71717a">Enforced in the hot path &#8212; before the request leaves OmniRoute · per-(key, model) caps · session stickiness</text>
</svg>

After

Width:  |  Height:  |  Size: 15 KiB