| <div class="fw-spec" style="width:100%;margin:14px 0;"></div> |
| <style> |
| .fw-spec { |
| border: 1px solid var(--border-color); |
| border-radius: 12px; |
| background: var(--surface-bg); |
| overflow: hidden; |
| color: var(--text-color); |
| } |
| .fw-spec__head { |
| display: flex; align-items: center; gap: 12px; |
| padding: 8px 12px; |
| border-bottom: 1px solid var(--border-color); |
| background: color-mix(in oklab, var(--muted-color) 4%, transparent); |
| flex-wrap: wrap; |
| } |
| .fw-spec__title { |
| font-size: 10.5px; |
| font-weight: 800; |
| letter-spacing: 1px; |
| text-transform: uppercase; |
| color: var(--muted-color); |
| margin-right: auto; |
| } |
| .fw-spec__legend { |
| display: inline-flex; align-items: center; gap: 8px; |
| font-size: 10.5px; color: var(--muted-color); |
| } |
| |
| .fw-spec__grid { |
| display: grid; |
| grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); |
| gap: 10px; |
| padding: 12px; |
| background: color-mix(in oklab, var(--muted-color) 3%, transparent); |
| } |
| |
| .fws-card { |
| position: relative; |
| border-radius: 12px; |
| padding: 16px 16px 14px 16px; |
| overflow: hidden; |
| background: linear-gradient(135deg, |
| color-mix(in oklab, var(--c) 22%, var(--surface-bg)) 0%, |
| color-mix(in oklab, var(--c) 6%, var(--surface-bg)) 60%, |
| var(--surface-bg) 100%); |
| border: 1px solid color-mix(in oklab, var(--c) 30%, var(--border-color)); |
| display: flex; flex-direction: column; gap: 10px; |
| min-width: 0; |
| transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease; |
| } |
| .fws-card:hover { |
| transform: translateY(-2px); |
| border-color: color-mix(in oklab, var(--c) 55%, var(--border-color)); |
| box-shadow: 0 6px 18px color-mix(in oklab, var(--c) 16%, transparent); |
| } |
| .fws-card::after { |
| content: ""; |
| position: absolute; |
| inset: 0 0 auto 0; |
| height: 3px; |
| background: linear-gradient(90deg, var(--c), color-mix(in oklab, var(--c) 50%, transparent)); |
| } |
| |
| .fws-card__top { |
| display: flex; align-items: flex-start; gap: 10px; |
| } |
| .fws-card__top .name-block { flex: 1; min-width: 0; } |
| .fws-card__top .name { |
| font-size: 18px; |
| font-weight: 800; |
| color: var(--text-color); |
| line-height: 1.2; |
| letter-spacing: -0.01em; |
| } |
| .fws-card__top .creator { |
| font-size: 11px; |
| color: var(--muted-color); |
| font-weight: 600; |
| margin-top: 2px; |
| } |
| .fws-card__transport { |
| display: inline-flex; align-items: center; gap: 4px; |
| padding: 3px 9px; |
| border-radius: 999px; |
| font-size: 10px; |
| font-weight: 800; |
| text-transform: uppercase; |
| letter-spacing: 0.5px; |
| flex-shrink: 0; |
| border: 1px solid color-mix(in oklab, var(--c) 35%, var(--border-color)); |
| background: color-mix(in oklab, var(--c) 16%, transparent); |
| color: var(--text-color); |
| } |
| |
| .fws-card__tagline { |
| font-size: 12px; |
| color: var(--muted-color); |
| line-height: 1.5; |
| font-style: italic; |
| margin: 0; |
| } |
| |
| .fws-card__kpis { |
| display: grid; |
| grid-template-columns: repeat(3, 1fr); |
| gap: 6px; |
| padding: 8px 10px; |
| border-radius: 8px; |
| background: color-mix(in oklab, var(--surface-bg) 80%, transparent); |
| border: 1px solid color-mix(in oklab, var(--c) 18%, var(--border-color)); |
| } |
| .fws-card__kpi { |
| display: flex; flex-direction: column; gap: 2px; |
| min-width: 0; |
| } |
| .fws-card__kpi .k { |
| font-size: 9px; |
| font-weight: 800; |
| text-transform: uppercase; |
| letter-spacing: 0.6px; |
| color: var(--muted-color); |
| } |
| .fws-card__kpi .v { |
| font-size: 11.5px; |
| font-weight: 700; |
| color: var(--text-color); |
| overflow: hidden; |
| text-overflow: ellipsis; |
| white-space: nowrap; |
| } |
| .fws-card__kpi .v code { |
| background: transparent; |
| padding: 0; |
| color: inherit; |
| font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; |
| font-size: 11px; |
| } |
| |
| .fws-card__links { |
| display: flex; gap: 6px; |
| margin-top: auto; |
| flex-wrap: wrap; |
| } |
| .fws-card__link { |
| display: inline-flex; align-items: center; gap: 5px; |
| font-size: 11px; |
| font-weight: 700; |
| color: var(--text-color); |
| text-decoration: none; |
| padding: 5px 10px; |
| border-radius: 6px; |
| border: 1px solid color-mix(in oklab, var(--c) 30%, var(--border-color)); |
| background: color-mix(in oklab, var(--c) 12%, transparent); |
| transition: filter 0.15s ease, transform 0.15s ease; |
| } |
| .fws-card__link:hover { filter: brightness(1.15); } |
| .fws-card__link svg { width: 11px; height: 11px; } |
| .fws-card__link.muted { |
| color: var(--muted-color); |
| background: transparent; |
| border-color: var(--border-color); |
| } |
| .fws-card__link.muted:hover { |
| color: var(--text-color); |
| border-color: var(--text-color); |
| } |
| </style> |
| <script> |
| (() => { |
| const bootstrap = () => { |
| const scriptEl = document.currentScript; |
| let container = scriptEl ? scriptEl.previousElementSibling : null; |
| if (!(container && container.classList && container.classList.contains('fw-spec'))) { |
| const cands = Array.from(document.querySelectorAll('.fw-spec')) |
| .filter(el => !(el.dataset && el.dataset.mounted === 'true')); |
| container = cands[cands.length - 1] || null; |
| } |
| if (!container || (container.dataset && container.dataset.mounted === 'true')) return; |
| container.dataset.mounted = 'true'; |
| |
| const FRAMEWORKS = [ |
| { |
| name: 'OpenEnv', creator: 'Meta PyTorch', |
| color: '#3b82f6', transport: 'HTTP · MCP', |
| tagline: 'Protocol-first. Sessions, transport, and a composable Rubric reward system; bring your own tasks.', |
| kpis: { 'Built-ins': 'Community', 'Python': '≥3.11', 'Package': '<code>openenv-core</code>' }, |
| repo: 'https://github.com/meta-pytorch/OpenEnv', |
| space: 'https://huggingface.co/spaces/AdithyaSK/jupyter-agent-openenv', |
| }, |
| { |
| name: 'ORS', creator: 'General Reasoning', |
| color: '#a855f7', transport: 'HTTP · REST + SSE', |
| tagline: 'Open Reward Standard. Per-tool-call rewards on a hub-shipped catalog of 330+ envs.', |
| kpis: { 'Built-ins': '330+ on hub', 'Python': '≥3.10', 'Package': '<code>ors-sdk</code>' }, |
| repo: 'https://openrewardstandard.io/', |
| space: 'https://huggingface.co/spaces/AdithyaSK/jupyter-agent-ors', |
| }, |
| { |
| name: 'NeMo Gym', creator: 'NVIDIA', |
| color: '#22c55e', transport: 'HTTP · REST', |
| tagline: 'FastAPI endpoints for tools, post-episode <code>/verify</code> for reward. Ships with Ray.', |
| kpis: { 'Built-ins': '50+', 'Python': '≥3.12', 'Package': '<code>nemo_gym</code> (git)' }, |
| repo: 'https://github.com/NVIDIA-NeMo/Gym', |
| space: 'https://huggingface.co/spaces/AdithyaSK/jupyter-agent-nemo-gym', |
| }, |
| { |
| name: 'Verifiers', creator: 'PrimeIntellect', |
| color: '#ec4899', transport: 'In-process', |
| tagline: 'Most batteries included. Datasets, tools, Rubric, rollout harness, and bundled training via Prime RL.', |
| kpis: { 'Built-ins': 'Community', 'Python': '≥3.11', 'Package': '<code>verifiers</code>' }, |
| repo: 'https://github.com/PrimeIntellect-ai/verifiers', |
| space: null, |
| }, |
| { |
| name: 'SkyRL Gym', creator: 'NovaSky-AI · Berkeley', |
| color: '#f59e0b', transport: 'In-process', |
| tagline: 'Gym-style <code>BaseTextEnv</code> + <code>ToolGroup</code>. Trained SkyRL-Agent for SWE-Bench.', |
| kpis: { 'Built-ins': 'Few', 'Python': '≥3.10', 'Package': '<code>skyrl-gym</code>' }, |
| repo: 'https://github.com/NovaSky-AI/SkyRL/tree/main/skyrl-gym', |
| space: null, |
| }, |
| { |
| name: 'GEM', creator: 'Axon-RL', |
| color: '#14b8a6', transport: 'In-process', |
| tagline: 'Closest to classical Gymnasium. 24+ built-in envs across games, math, and code.', |
| kpis: { 'Built-ins': '24+ envs', 'Python': '≥3.10', 'Package': '<code>gem-llm</code>' }, |
| repo: 'https://github.com/axon-rl/gem', |
| space: null, |
| }, |
| ]; |
| |
| const ICON_REPO = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 .3a12 12 0 0 0-3.8 23.4c.6.1.8-.3.8-.6v-2c-3.3.7-4-1.4-4-1.4-.6-1.4-1.4-1.8-1.4-1.8-1.1-.8.1-.7.1-.7 1.2.1 1.8 1.2 1.8 1.2 1.1 1.8 2.8 1.3 3.5 1 .1-.8.4-1.3.8-1.6-2.7-.3-5.5-1.3-5.5-6 0-1.3.5-2.4 1.2-3.2-.1-.3-.5-1.5.1-3.2 0 0 1-.3 3.3 1.2a11 11 0 0 1 6 0c2.3-1.5 3.3-1.2 3.3-1.2.6 1.7.2 2.9.1 3.2.8.8 1.2 1.9 1.2 3.2 0 4.7-2.8 5.7-5.5 6 .4.4.8 1.1.8 2.2v3.3c0 .3.2.7.8.6A12 12 0 0 0 12 .3Z"/></svg>'; |
| const ICON_EXT = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M14 3h7v7"/><path d="M21 3l-9 9"/><path d="M21 14v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5"/></svg>'; |
| |
| const cardsHtml = FRAMEWORKS.map(f => { |
| const kpis = Object.entries(f.kpis).map(([k, v]) => ` |
| <div class="fws-card__kpi"> |
| <span class="k">${k}</span> |
| <span class="v">${v}</span> |
| </div> |
| `).join(''); |
| const repoLink = f.repo |
| ? `<a class="fws-card__link" href="${f.repo}" target="_blank" rel="noopener">${ICON_REPO} repo</a>` |
| : ''; |
| const spaceLink = f.space |
| ? `<a class="fws-card__link muted" href="${f.space}" target="_blank" rel="noopener">${ICON_EXT} HF Space</a>` |
| : ''; |
| return ` |
| <article class="fws-card" style="--c:${f.color};"> |
| <div class="fws-card__top"> |
| <div class="name-block"> |
| <div class="name">${f.name}</div> |
| <div class="creator">${f.creator}</div> |
| </div> |
| <span class="fws-card__transport">${f.transport}</span> |
| </div> |
| <p class="fws-card__tagline">${f.tagline}</p> |
| <div class="fws-card__kpis">${kpis}</div> |
| <div class="fws-card__links">${repoLink}${spaceLink}</div> |
| </article> |
| `; |
| }).join(''); |
| |
| container.innerHTML = ` |
| <div class="fw-spec__head"> |
| <span class="fw-spec__title">Six framework spec cards</span> |
| <span class="fw-spec__legend">3 stats · creator · transport · repo</span> |
| </div> |
| <div class="fw-spec__grid">${cardsHtml}</div> |
| `; |
| }; |
| |
| if (document.readyState === 'loading') { |
| document.addEventListener('DOMContentLoaded', bootstrap, { once: true }); |
| } else { |
| bootstrap(); |
| } |
| })(); |
| </script> |
|
|