diff --git a/docs/superpowers/specs/2026-04-07-landing-overdrive-fused-design.md b/docs/superpowers/specs/2026-04-07-landing-overdrive-fused-design.md new file mode 100644 index 0000000..2c35ae8 --- /dev/null +++ b/docs/superpowers/specs/2026-04-07-landing-overdrive-fused-design.md @@ -0,0 +1,257 @@ +# Landing Overdrive — Fused Design Spec + +**Date**: 2026-04-07 +**Branch**: `feat/landing-overdrive-fused` +**Driver**: Replace 6 templated sections + footer + wordmark on `landing/index.html` with a unified, technically ambitious treatment that lives up to the .impeccable.md design principles. + +## Why this exists + +The user identified 6 sections of `landing/index.html` that read as "AI slop" — templated rectangular content blocks with the same code-on-one-side / cards-on-the-other geometry. Even when individual content is good, the uniform composition makes the page blur together. The /bolder + /animate + /delight + /overdrive skill stack was invoked to give each section its own visual genre and tie them together with a unified animating principle. + +The solution is **A+C fused** (Direction A "Living Documentation" + Direction C "Agent in Motion") with C reframed to strip the cuteness: instead of an agent character, the page is unified by an **execution pointer** — an abstract cyan pulse that represents where the program is executing right now, like a debugger step indicator. + +## The animating principle: the execution pointer + +There is one persistent visual concept across the page: a small cyan pulse called the **execution pointer**. It is **not a single DOM node moving across the page** — it is a conceptual entity, implemented as section-local animations that share the same color, easing curves, and timing language. + +**Why section-local instead of global**: a page-spanning element creates performance hazards (constant scroll listeners, layout thrash) and accessibility hazards (one element responsible for too much motion). Section-local animations are individually controlled by `IntersectionObserver`, paused when off-screen, and degrade independently. + +**Visual specification**: +- Color: brand cyan `#22d3ee` (same as existing accent) +- Default form: `8px` cyan dot with `0 0 16px rgba(34, 211, 238, 0.6)` glow +- Default motion: pulses on a 1.6s loop with `cubic-bezier(0.4, 0, 0.6, 1)` +- Section variants: scan line (sweeps horizontally), step indicator (jumps between graph nodes), caret (blinks at end of text), stamp (pulses on element entry) + +**The pointer is the cohesion**. Every section's hero animation uses one of these forms. Users will not consciously notice the connection — they will feel the page hangs together. + +## Section specifications + +Each section below has: **what it replaces**, **the new treatment**, **the hero moment**, **mobile fallback**, **reduced-motion fallback**. + +### Section 1 — `#what-is` "What is Selectools?" + +**Replaces**: Bullet stack on the left + generic Mac terminal code window on the right. + +**New treatment**: A single full-width terminal panel. The pointer types out a `pip install` → `python hello.py` session in real time. As the script runs, the capability tags (Multi-agent graphs, Tool calling, Hybrid RAG, 50 evaluators, Guardrails, Audit logging, Visual builder) **light up in sync with the lines that import them**. The tags are not a list — they are a runtime trace. + +Layout: terminal panel takes ~60% of the column, capability tags become a rail down the right side that "lights up" line by line. Section heading sits above. + +**Hero moment**: When the section enters the viewport, the pointer types `>>> from selectools import Agent` and the "Multi-agent graphs" tag pulses cyan. Then `>>> agent = Agent(tools=[search])` and "Tool calling" pulses. The sequence is choreographed so each line earns its tag. + +**Mobile fallback** (`pointer: coarse`): same animation, plays on viewport entry as a one-shot. Tags wrap below the terminal instead of right rail. + +**Reduced-motion fallback**: terminal renders fully complete, all tags pre-lit. Static. Still tells the same story. + +### Section 2 — `#see-the-difference` "See the difference" + +**Replaces**: Side-by-side LangGraph (25 lines) vs selectools (1 line) code blocks + green checkmark list. + +**New treatment**: A horizontal **drag-to-compare slider** between the two code blocks. Default position: 50/50. Drag the cyan handle right to wipe LangGraph away and reveal more selectools; drag left to do the opposite. As you drag past key positions, **inline annotations appear** (the four old checkmarks: "Plain Python", "HITL resumes at yield point", "Zero extra deps", "Deploy with `selectools serve`"). The annotations are positioned at the line numbers where the corresponding pain point lives in the LangGraph code, so they earn their place by tying to specific ceremony. + +**Hero moment**: On viewport entry, the slider auto-demonstrates by sweeping from 50/50 → 100% selectools → 50/50 once, then sits idle awaiting user drag. The pointer is the slider handle. + +**Mobile fallback**: drag-to-compare doesn't work cleanly on touch. Replaced with a tap-to-flip card: tap to show LangGraph, tap to show selectools. Annotations still appear inline. + +**Reduced-motion fallback**: no auto-sweep. Slider sits at 50/50, fully usable as static comparison. + +### Section 3 — `#production-ready` "Production-ready" + +**Replaces**: `agent.py` code window on the left + 4 stacked `result.*` cards on the right. + +**New treatment**: Code window stays on the left. Right side becomes an **interactive trace explorer**. The agent loop is rendered as a horizontal sequence of clickable nodes: `llm_call → tool_selection → tool_execution → llm_call`. Below the nodes, there's a single result panel that swaps content based on which node is active. Default: `llm_call` is active showing `result.content`. Click any node to swap the panel. + +The 4 old cards (`result.content` / `result.reasoning` / `result.trace` / `result.usage`) become the 4 panel states: each step of the agent loop reveals one of them. + +**Hero moment**: On viewport entry, the pointer travels through the trace nodes one by one (`llm_call → tool_selection → tool_execution → llm_call`), and the result panel below auto-swaps to match. After the auto-play finishes, the user can click any node to inspect. + +**Mobile fallback**: nodes stack vertically. Auto-play still runs. Tap to swap. + +**Reduced-motion fallback**: all 4 nodes pre-rendered as a static row. Result panel defaults to `result.trace` (the most informative). User can still click to swap. + +### Section 4 — `#enterprise-ready` "Enterprise-ready" + +**Replaces**: A single full-width pill row card with `SBOM (CycloneDX) · Security audit published · @stable / @beta / @deprecated · Python 3.9 to 3.13 · 95% test coverage · 4612 tests`. + +**New treatment**: A **compliance shelf** with 5 distinct artifacts laid out as exhibits in a grid. Each exhibit has its own micro-component: + +1. **Coverage ring** — animated SVG circular gauge climbing from 0% to 95% on viewport entry. JetBrains Mono number in the center. +2. **Test counter** — large number that ticks from 0 to 4612 with `requestAnimationFrame` easing. "tests passing" caption beneath. +3. **Version stack** — a vertical strip showing `3.9 / 3.10 / 3.11 / 3.12 / 3.13` like a compatibility ladder, each rung lighting up as the pointer climbs it. +4. **CycloneDX SBOM card** — a paper-document-style card with a folded corner, "CycloneDX 1.5" label, and a tiny barcode pattern. Static visual exhibit. +5. **Audit doc** — a stamped-document visual with `@stable / @beta / @deprecated` rendered as colored stamps. + +Layout: 5-column grid on desktop, 2-column on tablet, 1-column on mobile. Section header sits above. + +**Hero moment**: Pointer becomes a stamp. As each exhibit enters the viewport, the pointer "stamps" it — the exhibit pulses cyan, then settles into its rest state. Sequence is staggered by ~150ms per exhibit. + +**Mobile fallback**: same animations, played sequentially on viewport entry, single column. + +**Reduced-motion fallback**: all exhibits in their final state. Coverage ring at 95%, counter at 4612, version stack fully lit. + +### Section 5 — `#evals` "Built-in evaluation" + +**Replaces**: `test_agent.py` code window + 3 cards (Deterministic chips, LLM-as-Judge chips, Infrastructure checkmarks). + +**New treatment**: Code window stays on the left. Right side becomes a **live test report skeleton** that fills in as the script "runs". The report is a **hardcoded mock**, not a real test runner — it hardcodes the same metrics that the existing static cards display (accuracy 1.0, latency p50 142ms, cost $0.002). The "running" effect is purely visual choreography. The report has: +- A header bar mimicking real test runner output (`Running 1 test... ✓ 1 passed in 142ms`) +- Three metric rows: accuracy bar (climbs to 100%), latency p50 (ticks to 142ms), total cost (ticks to $0.002) +- A status badge ("PASSED" with green dot) + +Below the report (and below the code), spanning full width, sits a **2-row marquee of all 50 evaluator names** scrolling in opposite directions: deterministic evaluators on top, LLM-judge evaluators on bottom. Speed: ~32s and ~38s loops. Too many to count, which is the point. + +**Hero moment**: Pointer enters the code window, the cursor steps through the `EvalSuite` definition, then "runs" — the report on the right fills in metric by metric. Once metrics are filled, the marquee starts scrolling. + +**Mobile fallback**: report and code stack vertically. Marquee still runs, narrower viewport. + +**Reduced-motion fallback**: report fully filled in. Marquee replaced with a static 2-column grid of all 50 evaluator names. + +### Section 6 — `#faq` "Frequently asked questions" + +**Replaces**: 10 stacked accordion buttons. + +**New treatment**: A **`selectools docs` REPL**. Layout: +- Search bar at top, prompt-styled (`docs > _`) +- Left rail: category tabs (`# getting-started`, `# concepts`, `# providers`, `# advanced`) +- Main panel: questions render as `?` prompts in JetBrains Mono. When clicked (or auto-selected), the answer streams in below in monospace, with **inline syntax-highlighted code blocks** where relevant. + +Search filters questions in real time as the user types. Categories filter by tag. The answer panel feels like reading docs in a terminal. + +**Hero moment**: On viewport entry, the pointer types the first question into the search bar (`How is Selectools different from LangChain?`) and the answer streams in character-by-character. Then idles, awaiting user input. + +**Mobile fallback**: left rail collapses into a horizontal scroll of category chips above the panel. Search bar stays. Animations same. + +**Reduced-motion fallback**: search bar empty. First question selected by default. Answer rendered in full immediately. + +### Footer + +**Replaces**: Whatever is currently there (3-column links + legal). + +**New treatment**: A **terminal sitemap**. Renders as `$ tree selectools.dev/` output: + +``` +$ tree selectools.dev/ +. +├── docs/ +│ ├── quickstart.md +│ ├── concepts.md +│ ├── providers.md +│ └── api-reference/ +├── examples/ # 88 numbered scripts +├── builder/ # visual flow editor +├── github/ # source + issues +└── pypi/ # pip install selectools + +# selectools v0.20.1 · Apache-2.0 · NichevLabs +# made for developers who ship +$ _ +``` + +Each path is a hover-highlighted link. The trailing `$ _` has a blinking caret that never stops — the page is "still running". Social/legal/version inline as `# comments` in the dev-grey color. + +**Mobile fallback**: same layout, JetBrains Mono shrinks to fit, paths wrap on long lines. + +**Reduced-motion fallback**: caret static, no blink. + +## Wordmark — three switchable variants + +All three are built and switchable via `?logo=1|2|3` URL param. Default is variant `1`. The user picks the winner visually after seeing all three live. + +### Variant 1 — `[•] selectools` + +A pulsing cyan dot inside square brackets, followed by the wordmark in Plus Jakarta Sans semibold. The dot pulses on a 1.6s loop. Hover: brightens. Page load: one strong pulse. + +**Favicon**: the bracket-dot reduces cleanly to 16×16 (`[•]` in cyan on slate). Written to `landing/favicon.svg` (the active favicon when Variant 1 is the default). + +**State variants** for reuse elsewhere: `[• ]` (idle), `[•]` (running), `[✓]` (done), `[✗]` (error). + +### Variant 2 — `s▌electools` + +A block cursor `▌` lives inside the wordmark. On page load, types out: `s▌` → `se▌` → `sel▌` → ... → `selectools▌`. After type-on, the cursor settles between `s` and `e` and blinks there forever. Hover: cursor jumps to the position you hover over. + +**Favicon**: paired with a standalone `▌` block-cursor mark, written to `landing/favicon.svg` only when Variant 2 is the active default. Since the default is Variant 1, this favicon ships as `landing/favicon-cursor.svg` for reference and only swaps in if the user picks Variant 2 as the winner. + +### Variant 3 — Terminal banner art + +A 6-row box-drawing block-glyph rendering of `SELECTOOLS` set in JetBrains Mono. Cyan-on-slate. On page load, the execution pointer runs a **scan line across the top edge of the glyphs** like a dot-matrix printer printing the banner. After scan completes, the whole banner gets one strong glow pulse and settles. + +On scroll, in the sticky header, the banner **collapses** into a single-row `> selectools` prompt to save vertical space. View Transitions API (same-document mode, supported in all evergreen browsers as of 2025 — no Firefox fallback needed) morphs between the two states cleanly. If `document.startViewTransition` is missing, the swap is instant with a brief opacity crossfade fallback. + +**Mobile**: full 6-row banner doesn't fit at 360px. Replaced with a 3-row compact box-drawing version that fits: + +``` +┌─┐┌─┐┬ ┌─┐┌─┐┌┬┐┌─┐┌─┐┬ ┌─┐ +└─┐├┤ │ ├┤ │ │ │ ││ ││ └─┐ +└─┘└─┘┴─┘└─┘└─┘ ┴ └─┘└─┘┴─┘└─┘ +``` + +**Favicon**: standalone `▌` block-cursor mark (same as Variant 2 — they share the cursor glyph). Same `landing/favicon-cursor.svg` reference file. Becomes the active `landing/favicon.svg` only if the user picks Variant 3 as the winner. + +**Accessibility**: full banner gets `aria-hidden="true"`. An adjacent visually-hidden `

selectools

` carries the semantic content for screen readers. + +## Implementation order + +Single PR, atomic commits per section so review stays clean in `git log -p`. Build order is chosen to minimize cross-section CSS conflicts: + +1. **Setup commit**: branch from `main`, create CSS architecture for execution-pointer system (shared variables for color, easing, timing). Add `IntersectionObserver` helpers. +2. **Section 1** (What is Selectools?) — establishes the terminal-typing pattern other sections will reuse. +3. **Section 5** (Built-in evaluation) — reuses Section 1's terminal pattern, adds report skeleton. +4. **Section 3** (Production-ready) — introduces the trace-explorer pattern. +5. **Section 2** (See the difference) — introduces the drag-to-compare pattern (more isolated, lower reuse). +6. **Section 4** (Enterprise-ready) — compliance shelf, no shared patterns with other sections. +7. **Section 6** (FAQ) — REPL pattern, reuses terminal styling from Section 1. +8. **Footer** — terminal sitemap, reuses terminal styling. +9. **Wordmark variants** — all three built, default is Variant 1, query param to switch. +10. **Final cleanup commit**: cross-section testing, reduced-motion audit, mobile audit, copy polish. + +Each commit gets a Playwright visual check before moving to the next. + +## Performance budget + +`landing/index.html` is a single self-contained file with inline ` - - - - - - - -
-
-
-
- -

AI agents that are just Python.

-

- Multi-agent graphs, tool calling, RAG, 50 evaluators, and a drag-drop visual builder. All in one pip install. No DSL to learn. No SaaS to pay for. No vendor to depend on. -

-
-
- - - - ~/your-project - -
-
- $pip install selectools -
-
- -
- Works with -
- OpenAI - Anthropic - Gemini - Ollama -
-
-
-
-
-
-
- - -
-
-
-
- - -
-
-
152 models
-
4612 tests
-
95% coverage
-
88 examples
-
50 evaluators
-
4 providers
-
v0.20.1
-
-
- - -
-
- -

Watch agents work. In real time.

-

Pre-recorded traces from real selectools agents. Routing, tool calls, failover, RAG. No API key needed.

- -
- - - - - - - - - - -
+ /* ════════════════════════════════════════════════════════════════ + OVERDRIVE FUSED — execution-pointer system (shared atoms) + Reusable building blocks for all six redesigned sections. + Each section composes these atoms to create its hero moment; + the visual cohesion comes from sharing color, easing, and timing. + Consumers: #what, #see-difference, #production, #enterprise, + #eval, #faq, footer, wordmarks. + ════════════════════════════════════════════════════════════════ */ -
-
-
-
-
-
-
- Customer Support Router - ready -
-
-
-
-
-
-
Elapsed
-
0.0s
-
-
-
Events
-
0 / 0
-
-
-
Model
-
--
-
-
-
Tokens
-
--
-
-
-
Cost
-
--
-
-
-
-
-
+ /* The pulse — a cyan dot that represents the live execution pointer. + Used standalone as a status indicator and inside section animations. */ + .exec-dot { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 999px; + background: var(--exec-color); + box-shadow: 0 0 0 0 var(--exec-glow); + animation: exec-pulse var(--exec-pulse-dur) var(--exec-ease-soft) infinite; + vertical-align: middle; + } + .exec-dot--lg { width: 10px; height: 10px; } + .exec-dot--sm { width: 6px; height: 6px; } - -
-
- -

A Python framework for production AI agents.

-
-
-

- Open-source Python library for production AI agents. One pip install gives you the full stack: -

-

- Multi-agent graphs · Tool calling · Hybrid RAG · 50 evaluators · Guardrails · Audit logging · Visual builder -

-

- No DSL. No separate packages. No paid SaaS. Your code stays plain Python — readable, debuggable, yours. -

-
-
-
-
-
-
-
- hello.py -
-
from selectools import Agent, tool -from selectools.providers import OpenAIProvider + @keyframes exec-pulse { + 0% { box-shadow: 0 0 0 0 var(--exec-glow); } + 60% { box-shadow: 0 0 0 8px rgba(34, 211, 238, 0); } + 100% { box-shadow: 0 0 0 0 rgba(34, 211, 238, 0); } + } -@tool() -def search(query: str) -> str: - """Search the knowledge base.""" - return db.search(query) + /* The caret — a blinking block-cursor used in terminals and the wordmark. */ + .exec-caret { + display: inline-block; + width: 0.55em; + height: 1.1em; + vertical-align: text-bottom; + background: var(--exec-color); + box-shadow: 0 0 6px var(--exec-glow); + animation: exec-blink var(--exec-blink-dur) steps(2, jump-none) infinite; + margin-left: 2px; + } + .exec-caret--thin { width: 2px; box-shadow: 0 0 4px var(--exec-glow-soft); } -agent = Agent( - tools=[search], - provider=OpenAIProvider(), -) -result = agent.run("Find our refund policy") -# result.content, result.trace, result.usage
-
-
-
-
-
+ @keyframes exec-blink { + 0%, 49% { opacity: 1; } + 50%, 100% { opacity: 0; } + } - -
-
- -

Three problems every agent team hits.

-

No paid debugger. No SaaS account. No bolt-on libraries. Just open the file, see the fix.

+ /* The scan line — a horizontal cyan beam that sweeps once across an element. + Used by the wordmark banner and Section 1 terminal on viewport entry. + Apply to a positioned parent: the ::after acts as the beam. */ + .exec-scan { position: relative; overflow: hidden; } + .exec-scan.in-view::after { + content: ""; + position: absolute; + top: 0; left: -25%; + width: 25%; + height: 100%; + background: linear-gradient( + 90deg, + rgba(34, 211, 238, 0) 0%, + rgba(34, 211, 238, 0.18) 40%, + rgba(34, 211, 238, 0.55) 50%, + rgba(34, 211, 238, 0.18) 60%, + rgba(34, 211, 238, 0) 100% + ); + pointer-events: none; + animation: exec-scan-sweep 1.4s var(--exec-ease-step) 0.2s 1 forwards; + } + @keyframes exec-scan-sweep { + 0% { transform: translateX(0); } + 100% { transform: translateX(520%); } + } -
+ /* The stamp — a one-shot scale + cyan ring used when the pointer "stamps" + an exhibit (Section 4 compliance shelf, Section 1 capability rail). */ + @keyframes exec-stamp { + 0% { transform: scale(0.92); box-shadow: 0 0 0 0 var(--exec-glow); } + 40% { transform: scale(1.02); box-shadow: 0 0 0 6px var(--exec-glow-soft); } + 100% { transform: scale(1); box-shadow: 0 0 0 1px rgba(34, 211, 238, 0.18); } + } -
-
01
-
+ /* ════════════════════════════════════════════════════════════════ + OVERDRIVE FUSED — #what — terminal + capability rail + Single full-width terminal panel that types out a script while + a vertical rail of capability chips lights up in sync with each + trigger line. The pointer (caret) lives at the end of the script. + ════════════════════════════════════════════════════════════════ */ + .what-stage { + display: grid; + grid-template-columns: 1.55fr 1fr; + gap: 36px; + align-items: stretch; + margin-top: 28px; + } + .what-term { + position: relative; + background: #0b1220; + border: 1px solid var(--border); + border-radius: 14px; + box-shadow: 0 20px 60px -28px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(34, 211, 238, 0.05); + overflow: hidden; + display: flex; + flex-direction: column; + } + .what-term__bar { + display: flex; + align-items: center; + gap: 8px; + padding: 12px 16px; + border-bottom: 1px solid var(--border); + background: rgba(15, 23, 42, 0.7); + } + .what-term__dot { + width: 11px; height: 11px; border-radius: 999px; + } + .what-term__dot--r { background: rgba(239, 68, 68, 0.85); } + .what-term__dot--y { background: rgba(250, 204, 21, 0.85); } + .what-term__dot--g { background: rgba(34, 197, 94, 0.85); } + .what-term__name { + margin-left: 8px; + font-family: var(--font-mono); + font-size: 12px; + color: var(--text-faint); + } + .what-term__shell { + margin-left: auto; + font-family: var(--font-mono); + font-size: 11px; + color: var(--text-faint); + letter-spacing: 0.08em; + } + .what-term__body { + padding: 22px 22px 26px; + font-family: var(--font-mono); + font-size: 13px; + line-height: 1.75; + color: var(--text); + flex: 1; + min-height: 380px; + } + .what-term__line { + display: block; + opacity: 0; + transform: translateY(4px); + transition: opacity 0.35s var(--exec-ease-soft), transform 0.35s var(--exec-ease-soft); + white-space: pre; + } + .what-term__line.is-blank { height: 0.95em; } + .what-term.in-view .what-term__line { opacity: 1; transform: translateY(0); } + .what-term.in-view .what-term__line:nth-child(1) { transition-delay: 0.10s; } + .what-term.in-view .what-term__line:nth-child(2) { transition-delay: 0.32s; } + .what-term.in-view .what-term__line:nth-child(3) { transition-delay: 0.54s; } + .what-term.in-view .what-term__line:nth-child(4) { transition-delay: 0.76s; } + .what-term.in-view .what-term__line:nth-child(5) { transition-delay: 0.98s; } + .what-term.in-view .what-term__line:nth-child(6) { transition-delay: 1.20s; } + .what-term.in-view .what-term__line:nth-child(7) { transition-delay: 1.42s; } + .what-term.in-view .what-term__line:nth-child(8) { transition-delay: 1.64s; } + .what-term.in-view .what-term__line:nth-child(9) { transition-delay: 1.86s; } + .what-term.in-view .what-term__line:nth-child(10) { transition-delay: 2.05s; } + .what-term.in-view .what-term__line:nth-child(11) { transition-delay: 2.24s; } + .what-term.in-view .what-term__line:nth-child(12) { transition-delay: 2.43s; } + .what-term.in-view .what-term__line:nth-child(13) { transition-delay: 2.62s; } + .what-term.in-view .what-term__line:nth-child(14) { transition-delay: 2.81s; } + .what-term.in-view .what-term__line:nth-child(15) { transition-delay: 3.00s; } + .what-term__line .kw { color: #c084fc; } + .what-term__line .cls { color: var(--cyan); } + .what-term__line .fn { color: #fbbf24; } + .what-term__line .str { color: #86efac; } + .what-term__line .cmt { color: var(--text-faint); font-style: italic; } + .what-term__caret { + display: inline-block; + width: 0.55em; + height: 1em; + vertical-align: text-bottom; + background: var(--exec-color); + box-shadow: 0 0 8px var(--exec-glow); + opacity: 0; + margin-left: 2px; + } + .what-term.in-view .what-term__caret { + opacity: 1; + animation: exec-blink var(--exec-blink-dur) steps(2, jump-none) 3.4s infinite; + } + + .what-rail { + display: flex; + flex-direction: column; + gap: 10px; + padding: 4px 0; + } + .what-rail__title { + font-family: var(--font-mono); + font-size: 10px; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--text-faint); + margin: 0 0 8px 4px; + display: flex; + align-items: center; + gap: 8px; + } + .what-chip { + display: flex; + align-items: center; + gap: 12px; + padding: 12px 14px; + border: 1px solid var(--border); + border-radius: 10px; + background: rgba(15, 23, 42, 0.45); + font-family: var(--font-ui); + font-size: 13.5px; + color: var(--text-dim); + transition: + border-color 0.5s var(--exec-ease-soft), + background 0.5s var(--exec-ease-soft), + color 0.5s var(--exec-ease-soft), + transform 0.5s var(--exec-ease-soft); + } + .what-chip__bullet { + width: 8px; height: 8px; border-radius: 999px; + background: var(--border); + box-shadow: 0 0 0 0 rgba(34, 211, 238, 0); + transition: background 0.4s var(--exec-ease-soft), box-shadow 0.4s var(--exec-ease-soft); + flex: 0 0 auto; + } + .what-chip__name { flex: 1; } + .what-chip__hint { + font-family: var(--font-mono); + font-size: 10.5px; + color: var(--text-faint); + letter-spacing: 0.04em; + } + .what-term.in-view ~ .what-rail .what-chip { /* fallback if rail comes after */ } + .what-stage.in-view .what-chip { + transition-delay: var(--chip-delay, 0s); + } + .what-stage.in-view .what-chip.is-lit { + border-color: rgba(34, 211, 238, 0.45); + background: rgba(34, 211, 238, 0.06); + color: var(--text); + } + .what-stage.in-view .what-chip.is-lit .what-chip__bullet { + background: var(--exec-color); + box-shadow: 0 0 0 4px var(--exec-glow-soft), 0 0 12px var(--exec-glow); + } + .what-stage.in-view .what-chip.is-lit .what-chip__hint { + color: var(--cyan); + opacity: 0.85; + } + + @media (max-width: 880px) { + .what-stage { grid-template-columns: 1fr; gap: 22px; } + .what-term__body { min-height: 340px; padding: 18px 16px 20px; font-size: 12px; } + .what-rail { gap: 8px; } + .what-chip { padding: 10px 12px; font-size: 13px; } + } + + /* ════════════════════════════════════════════════════════════════ + OVERDRIVE FUSED — #eval — live test report + 50-evaluator marquee + Code on the left stays. Right side is a hardcoded mock test + report that fills in metric-by-metric on viewport entry. Below + both: a 2-row marquee of all 50 evaluator names scrolling in + opposite directions (too many to count, which is the point). + ════════════════════════════════════════════════════════════════ */ + .eval-stage { + display: grid; + grid-template-columns: 1.1fr 0.9fr; + gap: 28px; + align-items: stretch; + margin-top: 28px; + } + .eval-report { + background: #0b1220; + border: 1px solid var(--border); + border-radius: 14px; + box-shadow: 0 20px 60px -28px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(34, 211, 238, 0.05); + overflow: hidden; + display: flex; + flex-direction: column; + } + .eval-report__bar { + display: flex; + align-items: center; + gap: 10px; + padding: 12px 16px; + border-bottom: 1px solid var(--border); + background: rgba(15, 23, 42, 0.7); + font-family: var(--font-mono); + font-size: 11px; + color: var(--text-faint); + } + .eval-report__bar .exec-dot { background: #f59e0b; box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.45); animation: eval-spinner 1.2s linear infinite; } + .eval-report.is-done .eval-report__bar .exec-dot { background: var(--green); box-shadow: 0 0 8px rgba(34, 197, 94, 0.6); animation: none; } + @keyframes eval-spinner { + 0%, 100% { transform: scale(0.9); opacity: 0.6; } + 50% { transform: scale(1.1); opacity: 1; } + } + .eval-report__title { + font-family: var(--font-mono); + font-size: 12px; + color: var(--text); + letter-spacing: 0.02em; + } + .eval-report__status { + margin-left: auto; + font-family: var(--font-mono); + font-size: 10px; + letter-spacing: 0.14em; + text-transform: uppercase; + padding: 4px 9px; + border-radius: 999px; + background: rgba(245, 158, 11, 0.12); + color: #f59e0b; + border: 1px solid rgba(245, 158, 11, 0.3); + transition: background 0.4s var(--exec-ease-soft), color 0.4s var(--exec-ease-soft), border-color 0.4s var(--exec-ease-soft); + } + .eval-report.is-done .eval-report__status { + background: rgba(34, 197, 94, 0.12); + color: var(--green); + border-color: rgba(34, 197, 94, 0.4); + } + .eval-report__body { + padding: 24px 22px 22px; + display: flex; + flex-direction: column; + gap: 22px; + flex: 1; + } + .eval-metric { display: flex; flex-direction: column; gap: 7px; } + .eval-metric__row { + display: flex; + align-items: baseline; + justify-content: space-between; + font-family: var(--font-mono); + font-size: 11px; + letter-spacing: 0.04em; + } + .eval-metric__label { color: var(--text-faint); text-transform: uppercase; } + .eval-metric__value { + color: var(--cyan); + font-size: 18px; + font-weight: 600; + letter-spacing: 0; + font-variant-numeric: tabular-nums; + } + .eval-metric__bar { + height: 6px; + border-radius: 999px; + background: rgba(34, 211, 238, 0.08); + overflow: hidden; + position: relative; + } + .eval-metric__bar::after { + content: ""; + position: absolute; + inset: 0; + width: 0%; + background: linear-gradient(90deg, var(--cyan), #67e8f9); + box-shadow: 0 0 12px var(--exec-glow); + transition: width 1.4s var(--exec-ease-soft); + } + .eval-report.is-running .eval-metric.is-acc .eval-metric__bar::after { width: 100%; transition-delay: 0.2s; } + .eval-report.is-running .eval-metric.is-lat .eval-metric__bar::after { width: 86%; transition-delay: 0.55s; background: linear-gradient(90deg, #fbbf24, #fde68a); box-shadow: 0 0 12px rgba(251, 191, 36, 0.45); } + .eval-report.is-running .eval-metric.is-cost .eval-metric__bar::after { width: 12%; transition-delay: 0.9s; background: linear-gradient(90deg, var(--green), #86efac); box-shadow: 0 0 12px rgba(34, 197, 94, 0.45); } + .eval-metric .eval-metric__value { opacity: 0; transform: translateY(2px); transition: opacity 0.5s var(--exec-ease-soft), transform 0.5s var(--exec-ease-soft); } + .eval-report.is-running .eval-metric.is-acc .eval-metric__value { opacity: 1; transform: none; transition-delay: 1.5s; } + .eval-report.is-running .eval-metric.is-lat .eval-metric__value { opacity: 1; transform: none; transition-delay: 1.85s; } + .eval-report.is-running .eval-metric.is-cost .eval-metric__value { opacity: 1; transform: none; transition-delay: 2.2s; } + + .eval-report__footer { + padding: 14px 22px 18px; + border-top: 1px solid var(--border); + display: flex; + align-items: center; + gap: 10px; + font-family: var(--font-mono); + font-size: 11px; + color: var(--text-faint); + } + .eval-report__footer code { color: var(--cyan); font-size: 11px; } + + /* The marquee — full-bleed under the stage */ + .eval-marquee { + margin-top: 28px; + border-top: 1px solid var(--border); + border-bottom: 1px solid var(--border); + background: rgba(15, 23, 42, 0.4); + padding: 16px 0; + display: flex; + flex-direction: column; + gap: 10px; + mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); + -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); + overflow: hidden; + } + .eval-marquee__label { + position: absolute; + left: 50%; + transform: translateX(-50%) translateY(-26px); + font-family: var(--font-mono); + font-size: 9px; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--text-faint); + background: var(--bg); + padding: 0 10px; + } + .eval-marquee__row { + display: flex; + gap: 10px; + width: max-content; + animation: eval-marquee-l 32s linear infinite; + } + .eval-marquee__row--rev { + animation: eval-marquee-r 38s linear infinite; + } + @keyframes eval-marquee-l { + 0% { transform: translateX(0); } + 100% { transform: translateX(-50%); } + } + @keyframes eval-marquee-r { + 0% { transform: translateX(-50%); } + 100% { transform: translateX(0); } + } + .eval-tag { + flex: 0 0 auto; + padding: 7px 13px; + border-radius: 999px; + border: 1px solid var(--border); + font-family: var(--font-mono); + font-size: 11px; + color: var(--text-dim); + background: rgba(15, 23, 42, 0.6); + letter-spacing: 0.02em; + } + .eval-tag--det { color: var(--cyan); border-color: rgba(34, 211, 238, 0.3); } + .eval-tag--judge { color: #93c5fd; border-color: rgba(147, 197, 253, 0.3); } + + @media (max-width: 880px) { + .eval-stage { grid-template-columns: 1fr; gap: 22px; } + .eval-report__body { padding: 18px 16px 18px; gap: 16px; } + .eval-metric__value { font-size: 16px; } + .eval-marquee { padding: 12px 0; } + .eval-tag { font-size: 10px; padding: 6px 10px; } + } + + /* ════════════════════════════════════════════════════════════════ + OVERDRIVE FUSED — #production — interactive trace explorer + Code on the left stays. Right side is a clickable agent loop: + 4 nodes (llm_call → tool_selection → tool_execution → llm_call) + above a single result panel that swaps content based on the + active node. Auto-plays once on viewport entry, then idles. + ════════════════════════════════════════════════════════════════ */ + .prod-stage { + display: grid; + grid-template-columns: 1.15fr 1fr; + gap: 28px; + align-items: stretch; + margin-top: 28px; + } + .prod-trace { + display: flex; + flex-direction: column; + gap: 18px; + padding: 4px 0; + } + .prod-trace__title { + font-family: var(--font-mono); + font-size: 10px; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--text-faint); + margin: 0 0 4px 4px; + display: flex; + align-items: center; + gap: 8px; + } + .prod-trace__nodes { + display: grid; + grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr; + align-items: center; + gap: 8px; + padding: 14px; + background: rgba(15, 23, 42, 0.45); + border: 1px solid var(--border); + border-radius: 12px; + } + .prod-node { + appearance: none; + background: rgba(15, 23, 42, 0.6); + border: 1px solid var(--border); + color: var(--text-dim); + font-family: var(--font-mono); + font-size: 11px; + padding: 10px 8px; + border-radius: 9px; + cursor: pointer; + text-align: center; + transition: + border-color 0.35s var(--exec-ease-soft), + background 0.35s var(--exec-ease-soft), + color 0.35s var(--exec-ease-soft), + transform 0.35s var(--exec-ease-soft), + box-shadow 0.35s var(--exec-ease-soft); + position: relative; + letter-spacing: 0.02em; + min-width: 0; + } + .prod-node:hover { color: var(--text); border-color: var(--text-faint); } + .prod-node:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; } + .prod-node.is-active { + border-color: var(--exec-color); + background: rgba(34, 211, 238, 0.1); + color: var(--cyan); + box-shadow: 0 0 0 4px var(--exec-glow-soft), 0 0 18px var(--exec-glow-soft); + transform: translateY(-1px); + } + .prod-node__num { + display: block; + font-size: 9px; + letter-spacing: 0.18em; + color: var(--text-faint); + margin-bottom: 4px; + } + .prod-node.is-active .prod-node__num { color: var(--cyan); opacity: 0.75; } + .prod-trace__arrow { + color: var(--border); + font-family: var(--font-mono); + font-size: 14px; + transition: color 0.35s var(--exec-ease-soft); + } + .prod-trace__arrow.is-passed { color: var(--exec-color); } + + .prod-panel { + flex: 1; + background: #0b1220; + border: 1px solid var(--border); + border-radius: 12px; + padding: 22px; + display: flex; + flex-direction: column; + gap: 14px; + min-height: 220px; + position: relative; + overflow: hidden; + } + .prod-panel__label { + font-family: var(--font-mono); + font-size: 10px; + letter-spacing: 0.14em; + text-transform: uppercase; + color: var(--text-faint); + display: flex; + align-items: center; + gap: 8px; + } + .prod-panel__label code { font-size: 11px; color: var(--cyan); } + .prod-panel__body { + font-family: var(--font-mono); + font-size: 13px; + line-height: 1.7; + color: var(--text); + } + .prod-panel__meta { + margin-top: auto; + padding-top: 14px; + border-top: 1px dashed var(--border); + display: flex; + gap: 16px; + font-family: var(--font-mono); + font-size: 11px; + color: var(--text-faint); + } + .prod-panel__meta strong { color: var(--green); font-weight: 500; } + .prod-panel__state { display: none; flex-direction: column; gap: 14px; flex: 1; } + .prod-panel__state.is-active { display: flex; } + .prod-panel__state .prod-panel__body { animation: prod-fade 0.4s var(--exec-ease-soft); } + @keyframes prod-fade { + from { opacity: 0; transform: translateY(4px); } + to { opacity: 1; transform: none; } + } + + @media (max-width: 880px) { + .prod-stage { grid-template-columns: 1fr; gap: 22px; } + .prod-trace__nodes { + grid-template-columns: 1fr; + gap: 10px; + } + .prod-trace__arrow { display: none; } + .prod-panel { min-height: 200px; padding: 18px; } + } + + /* ════════════════════════════════════════════════════════════════ + OVERDRIVE FUSED — #see-difference — drag-to-compare slider + LangGraph (25 lines) and selectools (1 line) stacked in the + same container. A range slider drags the split point left/right. + Annotations fade in as the slider passes their thresholds. + Auto-sweeps once on viewport entry, then idles awaiting drag. + ════════════════════════════════════════════════════════════════ */ + .diff-stage { + position: relative; + margin-top: 28px; + --split: 50; + } + .diff-pane { + position: relative; + border-radius: 14px; + overflow: hidden; + isolation: isolate; + min-height: 480px; + box-shadow: 0 20px 60px -28px rgba(0, 0, 0, 0.55); + display: grid; + /* Driven by --split (a unitless 0-100 value, JS keeps it in sync) */ + grid-template-columns: calc(var(--split) * 1%) calc((100 - var(--split)) * 1%); + gap: 0; + transition: grid-template-columns 0.6s var(--exec-ease-soft); + } + .diff-stage.is-dragging .diff-pane { transition: none; } + .diff-pane__col { + position: relative; + min-width: 0; /* allow column to shrink below content size */ + overflow: hidden; + border: 1px solid var(--border); + } + .diff-pane__col--l { border-right: none; border-radius: 14px 0 0 14px; } + .diff-pane__col--r { + border-left: none; + border-radius: 0 14px 14px 0; + border-color: rgba(34, 211, 238, 0.35); + box-shadow: inset 0 0 0 1px rgba(34, 211, 238, 0.08); + } + .diff-pane__col .code-frame { + height: 100%; + margin: 0; + border: none; + border-radius: 0; + box-shadow: none; + min-width: 0; + max-width: none; + } + .diff-pane__col--l .code-frame { background: #0b1220; } + .diff-pane__col--r .code-frame { background: #0a1220; } + .diff-pane__col .code-body { + height: calc(100% - 44px); + overflow: hidden; + mask-image: none; + -webkit-mask-image: none; + } + + /* The split handle line */ + .diff-pane__split-line { + position: absolute; + top: 0; + bottom: 0; + left: var(--split); + width: 2px; + background: var(--exec-color); + box-shadow: 0 0 12px var(--exec-glow), 0 0 0 1px rgba(11, 18, 32, 0.6); + transform: translateX(-1px); + pointer-events: none; + z-index: 3; + transition: left 0.6s var(--exec-ease-soft); + } + .diff-stage.is-dragging .diff-pane__split-line { transition: none; } + .diff-pane__split-knob { + position: absolute; + top: 50%; + left: var(--split); + width: 40px; + height: 40px; + transform: translate(-50%, -50%); + border-radius: 999px; + background: var(--bg); + border: 2px solid var(--exec-color); + box-shadow: 0 0 24px var(--exec-glow), 0 4px 12px rgba(0, 0, 0, 0.4); + pointer-events: none; + z-index: 4; + display: grid; + place-items: center; + color: var(--cyan); + font-family: var(--font-mono); + font-size: 14px; + font-weight: 700; + transition: left 0.6s var(--exec-ease-soft); + } + .diff-pane__split-knob::before { content: "‹"; transform: translateX(-2px); } + .diff-pane__split-knob::after { content: "›"; transform: translateX(2px); } + .diff-stage.is-dragging .diff-pane__split-knob { transition: none; } + + /* The actual range input — covers the entire pane, invisible thumb */ + .diff-pane__range { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + margin: 0; + padding: 0; + background: transparent; + border: none; + cursor: ew-resize; + z-index: 5; + -webkit-appearance: none; + appearance: none; + opacity: 0; + } + .diff-pane__range::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 60px; + height: 100%; + cursor: ew-resize; + } + .diff-pane__range::-moz-range-thumb { + width: 60px; + height: 100%; + cursor: ew-resize; + border: none; + background: transparent; + } + .diff-pane__range:focus-visible { outline: none; } + .diff-pane__range:focus-visible ~ .diff-pane__split-knob { + box-shadow: 0 0 0 4px var(--exec-glow-soft), 0 0 24px var(--exec-glow); + } + + /* Side labels — sit above the pane */ + .diff-labels { + display: flex; + justify-content: space-between; + margin-bottom: 10px; + font-family: var(--font-mono); + font-size: 11px; + letter-spacing: 0.04em; + color: var(--text-faint); + } + .diff-labels__l { color: var(--text-dim); } + .diff-labels__r { color: var(--cyan); } + + /* Drag hint below the pane */ + .diff-hint { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + margin-top: 14px; + font-family: var(--font-mono); + font-size: 11px; + color: var(--text-faint); + letter-spacing: 0.04em; + } + .diff-hint__bar { + flex: 1; + max-width: 60px; + height: 1px; + background: var(--border); + } + + /* Annotations — pop in as slider passes their thresholds */ + .diff-annotations { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 12px; + margin-top: 22px; + } + .diff-anno { + display: flex; + align-items: flex-start; + gap: 12px; + padding: 14px 16px; + border: 1px solid var(--border); + border-radius: 10px; + background: rgba(15, 23, 42, 0.45); + opacity: 0.35; + transform: translateY(4px); + transition: + opacity 0.45s var(--exec-ease-soft), + transform 0.45s var(--exec-ease-soft), + border-color 0.45s var(--exec-ease-soft), + background 0.45s var(--exec-ease-soft); + } + .diff-anno.is-shown { + opacity: 1; + transform: none; + border-color: rgba(34, 211, 238, 0.35); + background: rgba(34, 211, 238, 0.06); + } + .diff-anno__num { + flex: 0 0 auto; + width: 22px; + height: 22px; + border-radius: 999px; + background: rgba(34, 211, 238, 0.12); + color: var(--cyan); + font-family: var(--font-mono); + font-size: 10px; + display: grid; + place-items: center; + font-weight: 600; + } + .diff-anno.is-shown .diff-anno__num { + background: var(--exec-color); + color: var(--bg); + box-shadow: 0 0 0 3px var(--exec-glow-soft); + } + .diff-anno__text { + font-size: 13px; + color: var(--text); + line-height: 1.55; + } + .diff-anno__text code { color: var(--cyan); font-size: 12px; } + + @media (max-width: 880px) { + .diff-pane { min-height: 420px; } + .diff-pane__split-knob { width: 48px; height: 48px; font-size: 16px; } + .diff-annotations { grid-template-columns: 1fr; } + } + /* Mobile fallback: at narrow viewports, drag-to-compare is too tight to + read because each column shrinks below ~200px. Stack the two code + blocks vertically instead, both full-width. The slider, divider, and + knob are hidden — the comparison becomes static (LangGraph above, + selectools below) which is plenty for the message. */ + @media (max-width: 700px) { + .diff-pane { + grid-template-columns: 1fr !important; + grid-template-rows: auto auto; + min-height: 0; + } + .diff-pane__col { + height: auto; + } + .diff-pane__col .code-body { + height: auto; + max-height: 320px; + overflow-y: auto; + } + .diff-pane__col--l { + border-right: 1px solid var(--border); + border-bottom: none; + border-radius: 14px 14px 0 0; + } + .diff-pane__col--r { + border-left: 1px solid rgba(34, 211, 238, 0.35); + border-top: 1px solid rgba(34, 211, 238, 0.35); + border-radius: 0 0 14px 14px; + } + .diff-pane__split-line, + .diff-pane__split-knob, + .diff-pane__range { + display: none; + } + .diff-labels { display: none; } + .diff-hint { display: none; } + } + + /* ════════════════════════════════════════════════════════════════ + OVERDRIVE FUSED — #enterprise — compliance shelf (5 exhibits) + Replaces the sad full-width pill row that lived inside #features. + Now its own standalone section with 5 distinct micro-components: + coverage ring, test counter, version stack, SBOM card, audit doc. + The pointer "stamps" each exhibit on viewport entry, staggered. + ════════════════════════════════════════════════════════════════ */ + .ent-shelf { + display: grid; + grid-template-columns: repeat(5, 1fr); + gap: 18px; + margin-top: 28px; + } + .ent-exhibit { + position: relative; + background: rgba(15, 23, 42, 0.5); + border: 1px solid var(--border); + border-radius: 14px; + padding: 24px 20px 22px; + display: flex; + flex-direction: column; + gap: 10px; + min-height: 220px; + opacity: 0; + transform: translateY(8px); + transition: opacity 0.5s var(--exec-ease-soft), transform 0.5s var(--exec-ease-soft); + } + .ent-shelf.in-view .ent-exhibit { opacity: 1; transform: none; } + .ent-shelf.in-view .ent-exhibit:nth-child(1) { transition-delay: 0.05s; } + .ent-shelf.in-view .ent-exhibit:nth-child(2) { transition-delay: 0.18s; } + .ent-shelf.in-view .ent-exhibit:nth-child(3) { transition-delay: 0.31s; } + .ent-shelf.in-view .ent-exhibit:nth-child(4) { transition-delay: 0.44s; } + .ent-shelf.in-view .ent-exhibit:nth-child(5) { transition-delay: 0.57s; } + .ent-shelf.in-view .ent-exhibit::after { + content: ""; + position: absolute; + inset: 0; + border-radius: 14px; + pointer-events: none; + animation: exec-stamp 0.7s var(--exec-ease-step) both; + } + .ent-shelf.in-view .ent-exhibit:nth-child(1)::after { animation-delay: 0.10s; } + .ent-shelf.in-view .ent-exhibit:nth-child(2)::after { animation-delay: 0.23s; } + .ent-shelf.in-view .ent-exhibit:nth-child(3)::after { animation-delay: 0.36s; } + .ent-shelf.in-view .ent-exhibit:nth-child(4)::after { animation-delay: 0.49s; } + .ent-shelf.in-view .ent-exhibit:nth-child(5)::after { animation-delay: 0.62s; } + .ent-exhibit__label { + font-family: var(--font-mono); + font-size: 9px; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--text-faint); + } + .ent-exhibit__caption { + margin-top: auto; + font-size: 12.5px; + color: var(--text-dim); + line-height: 1.5; + } + + /* Exhibit 1: Coverage ring */ + .ent-ring { + width: 110px; + height: 110px; + margin: 8px auto 4px; + position: relative; + } + .ent-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); } + .ent-ring__track { fill: none; stroke: var(--border); stroke-width: 8; } + .ent-ring__fill { + fill: none; + stroke: var(--exec-color); + stroke-width: 8; + stroke-linecap: round; + stroke-dasharray: 314.16; /* 2 * π * 50 */ + stroke-dashoffset: 314.16; + filter: drop-shadow(0 0 8px var(--exec-glow)); + transition: stroke-dashoffset 1.4s var(--exec-ease-soft) 0.2s; + } + .ent-shelf.in-view .ent-ring__fill { stroke-dashoffset: 15.71; /* 95% → 314.16 * 0.05 */ } + .ent-ring__num { + position: absolute; + inset: 0; + display: grid; + place-items: center; + font-family: var(--font-mono); + font-size: 24px; + font-weight: 600; + color: var(--cyan); + font-variant-numeric: tabular-nums; + } + .ent-ring__num small { font-size: 13px; color: var(--text-faint); margin-left: 1px; } + + /* Exhibit 2: Test counter */ + .ent-counter { + flex: 1; + display: grid; + place-items: center; + padding: 10px 0; + } + .ent-counter__num { + font-family: var(--font-mono); + font-size: 42px; + font-weight: 700; + color: var(--exec-color); + font-variant-numeric: tabular-nums; + text-shadow: 0 0 20px var(--exec-glow-soft); + letter-spacing: -0.02em; + } + + /* Exhibit 3: Version stack */ + .ent-versions { + flex: 1; + display: flex; + flex-direction: column; + gap: 6px; + padding: 6px 0; + justify-content: center; + } + .ent-version { + display: flex; + align-items: center; + gap: 10px; + padding: 6px 12px; + border: 1px solid var(--border); + border-radius: 8px; + font-family: var(--font-mono); + font-size: 12px; + color: var(--text-dim); + transition: border-color 0.4s, color 0.4s, background 0.4s; + } + .ent-version__check { color: var(--text-faint); transition: color 0.4s; } + .ent-shelf.in-view .ent-version { + border-color: rgba(34, 211, 238, 0.3); + background: rgba(34, 211, 238, 0.05); + color: var(--text); + } + .ent-shelf.in-view .ent-version__check { color: var(--cyan); } + .ent-shelf.in-view .ent-version:nth-child(1) { transition-delay: 0.5s; } + .ent-shelf.in-view .ent-version:nth-child(2) { transition-delay: 0.6s; } + .ent-shelf.in-view .ent-version:nth-child(3) { transition-delay: 0.7s; } + .ent-shelf.in-view .ent-version:nth-child(4) { transition-delay: 0.8s; } + .ent-shelf.in-view .ent-version:nth-child(5) { transition-delay: 0.9s; } + + /* Exhibit 4: CycloneDX SBOM card */ + .ent-sbom { + flex: 1; + display: grid; + place-items: center; + padding: 8px 0; + } + .ent-sbom__doc { + width: 90px; + height: 110px; + background: linear-gradient(135deg, #1e2c44 0%, #0f1a2e 100%); + border: 1px solid rgba(34, 197, 94, 0.4); + border-radius: 6px; + position: relative; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4), inset 0 0 0 1px rgba(34, 197, 94, 0.08); + padding: 10px 8px 8px; + display: flex; + flex-direction: column; + gap: 4px; + } + .ent-sbom__doc::before { + /* Folded corner */ + content: ""; + position: absolute; + top: 0; right: 0; + width: 18px; + height: 18px; + background: linear-gradient(225deg, transparent 50%, rgba(34, 197, 94, 0.25) 50%, var(--bg) 51%); + } + .ent-sbom__doc::after { + content: "CycloneDX"; + position: absolute; + bottom: 6px; + left: 0; right: 0; + text-align: center; + font-family: var(--font-mono); + font-size: 8px; + letter-spacing: 0.1em; + color: var(--green); + text-transform: uppercase; + } + .ent-sbom__line { + height: 2px; + background: rgba(34, 197, 94, 0.25); + border-radius: 999px; + } + .ent-sbom__line--s { width: 60%; } + .ent-sbom__line--m { width: 80%; } + .ent-sbom__line--l { width: 95%; } + + /* Exhibit 5: Audit / markers */ + .ent-markers { + flex: 1; + display: flex; + flex-direction: column; + gap: 8px; + padding: 8px 0; + justify-content: center; + } + .ent-marker { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 12px; + border-radius: 8px; + background: rgba(168, 85, 247, 0.05); + border: 1px solid rgba(168, 85, 247, 0.18); + font-family: var(--font-mono); + font-size: 11px; + } + .ent-marker--stable { background: rgba(34, 197, 94, 0.06); border-color: rgba(34, 197, 94, 0.22); color: #86efac; } + .ent-marker--beta { background: rgba(245, 158, 11, 0.06); border-color: rgba(245, 158, 11, 0.22); color: #fde68a; } + .ent-marker--dep { background: rgba(239, 68, 68, 0.06); border-color: rgba(239, 68, 68, 0.22); color: #fca5a5; } + .ent-marker__dot { width: 6px; height: 6px; border-radius: 999px; background: currentColor; box-shadow: 0 0 6px currentColor; } + .ent-marker__name { font-weight: 600; } + .ent-marker__count { margin-left: auto; opacity: 0.7; } + + @media (max-width: 1080px) { + .ent-shelf { grid-template-columns: repeat(2, 1fr); } + .ent-exhibit { min-height: 200px; } + } + @media (max-width: 600px) { + .ent-shelf { grid-template-columns: 1fr; gap: 14px; } + .ent-counter__num { font-size: 36px; } + } + + /* ════════════════════════════════════════════════════════════════ + OVERDRIVE FUSED — #faq — selectools docs REPL + Replaces accordion with a search-driven docs REPL: prompt-styled + search bar at top, left rail of category tabs, questions render + as ? prompts in monospace, answers stream in below with inline + syntax-highlighted code blocks. + ════════════════════════════════════════════════════════════════ */ + .repl { + display: grid; + grid-template-columns: 200px 1fr; + gap: 0; + margin-top: 32px; + background: #0b1220; + border: 1px solid var(--border); + border-radius: 14px; + overflow: hidden; + box-shadow: 0 20px 60px -28px rgba(0, 0, 0, 0.55); + min-height: 540px; + } + .repl__rail { + background: rgba(15, 23, 42, 0.55); + border-right: 1px solid var(--border); + padding: 18px 0; + display: flex; + flex-direction: column; + gap: 2px; + } + .repl__rail-title { + font-family: var(--font-mono); + font-size: 9px; + letter-spacing: 0.18em; + text-transform: uppercase; + color: var(--text-faint); + padding: 0 18px 12px; + display: flex; + align-items: center; + gap: 8px; + } + .repl__cat { + appearance: none; + background: transparent; + border: none; + border-left: 2px solid transparent; + padding: 9px 18px; + font-family: var(--font-mono); + font-size: 12px; + color: var(--text-dim); + cursor: pointer; + text-align: left; + transition: color 0.25s, border-color 0.25s, background 0.25s; + display: flex; + align-items: center; + gap: 8px; + } + .repl__cat::before { content: "#"; color: var(--text-faint); } + .repl__cat:hover { color: var(--text); } + .repl__cat.is-active { + color: var(--cyan); + border-left-color: var(--cyan); + background: rgba(34, 211, 238, 0.06); + } + .repl__cat.is-active::before { color: var(--cyan); } + .repl__cat-count { + margin-left: auto; + font-size: 10px; + color: var(--text-faint); + background: rgba(34, 211, 238, 0.08); + padding: 1px 6px; + border-radius: 999px; + } + .repl__cat.is-active .repl__cat-count { color: var(--cyan); background: rgba(34, 211, 238, 0.15); } + + .repl__main { + display: flex; + flex-direction: column; + min-width: 0; + } + .repl__searchbar { + display: flex; + align-items: center; + gap: 10px; + padding: 14px 18px; + border-bottom: 1px solid var(--border); + background: rgba(15, 23, 42, 0.5); + font-family: var(--font-mono); + font-size: 12px; + } + .repl__prompt { color: var(--cyan); font-weight: 600; } + .repl__search { + flex: 1; + background: transparent; + border: none; + color: var(--text); + font-family: var(--font-mono); + font-size: 13px; + padding: 4px 0; + outline: none; + } + .repl__search::placeholder { color: var(--text-faint); } + .repl__searchbar .exec-caret { width: 7px; height: 14px; } + + .repl__list { + flex: 1; + padding: 8px 0 18px; + overflow-y: auto; + max-height: 540px; + } + .repl__q { + border-bottom: 1px solid rgba(51, 65, 85, 0.45); + } + .repl__q:last-child { border-bottom: none; } + .repl__q-summary { + list-style: none; + cursor: pointer; + padding: 14px 22px; + display: flex; + align-items: flex-start; + gap: 12px; + font-family: var(--font-mono); + font-size: 13px; + color: var(--text); + transition: background 0.2s, color 0.2s; + } + .repl__q-summary::-webkit-details-marker { display: none; } + .repl__q-summary:hover { background: rgba(34, 211, 238, 0.04); color: var(--cyan); } + .repl__q-marker { + color: var(--cyan); + font-weight: 700; + flex: 0 0 auto; + opacity: 0.7; + } + .repl__q[open] .repl__q-summary { color: var(--cyan); background: rgba(34, 211, 238, 0.05); } + .repl__q[open] .repl__q-marker { opacity: 1; } + .repl__q-text { flex: 1; } + .repl__q-cat { + font-size: 10px; + color: var(--text-faint); + letter-spacing: 0.06em; + flex: 0 0 auto; + opacity: 0.7; + } + .repl__q-answer { + padding: 0 22px 22px 50px; + color: var(--text-dim); + font-family: var(--font-ui); + font-size: 13.5px; + line-height: 1.75; + animation: repl-stream 0.5s var(--exec-ease-soft); + } + .repl__q-answer code { + font-family: var(--font-mono); + font-size: 12px; + color: var(--cyan); + background: rgba(34, 211, 238, 0.08); + padding: 1px 6px; + border-radius: 4px; + } + .repl__q-answer a { color: var(--cyan); } + @keyframes repl-stream { + 0% { opacity: 0; transform: translateY(2px); } + 100% { opacity: 1; transform: none; } + } + .repl__q.is-hidden { display: none; } + .repl__empty { + padding: 40px 22px; + text-align: center; + font-family: var(--font-mono); + font-size: 12px; + color: var(--text-faint); + display: none; + } + .repl.is-empty .repl__empty { display: block; } + + @media (max-width: 760px) { + .repl { grid-template-columns: 1fr; min-height: auto; } + .repl__rail { + flex-direction: row; + overflow-x: auto; + gap: 4px; + padding: 12px 14px; + border-right: none; + border-bottom: 1px solid var(--border); + } + .repl__rail-title { display: none; } + .repl__cat { + flex-shrink: 0; + border-left: none; + border-bottom: 2px solid transparent; + padding: 8px 12px; + } + .repl__cat.is-active { border-left-color: transparent; border-bottom-color: var(--cyan); } + .repl__list { max-height: 460px; } + .repl__q-summary { padding: 12px 16px; font-size: 12.5px; } + .repl__q-answer { padding: 0 16px 18px 38px; font-size: 13px; } + .repl__q-cat { display: none; } + } + + /* ════════════════════════════════════════════════════════════════ + OVERDRIVE FUSED — footer — terminal sitemap + Renders as `$ tree selectools.dev/` output: hover-highlighted + paths, social/legal/version inline as # comments, blinking caret + at the end (the page is "still running"). + ════════════════════════════════════════════════════════════════ */ + .footer-term { + max-width: var(--max-w); + margin: 0 auto; + padding: 50px 24px 60px; + font-family: var(--font-mono); + font-size: 13px; + line-height: 1.85; + color: var(--text-dim); + border-top: 1px solid var(--border); + background: + linear-gradient(180deg, transparent, rgba(34, 211, 238, 0.02)); + } + .footer-term__prompt { + color: var(--text-faint); + margin-bottom: 8px; + } + .footer-term__prompt .pr { color: var(--cyan); margin-right: 6px; } + .footer-term__tree { white-space: pre; overflow-x: auto; padding-bottom: 6px; } + .footer-term__tree a { + color: var(--text-dim); + text-decoration: none; + transition: color 0.2s, background 0.2s, text-shadow 0.2s; + padding: 0 2px; + border-radius: 2px; + } + .footer-term__tree a:hover { + color: var(--cyan); + background: rgba(34, 211, 238, 0.08); + text-shadow: 0 0 8px var(--exec-glow); + } + .footer-term__cmt { + color: var(--text-faint); + font-style: italic; + opacity: 0.85; + } + .footer-term__heart { color: var(--cyan); } + .footer-term__nichev a { color: var(--cyan); } + .footer-term__final { + margin-top: 14px; + display: flex; + align-items: center; + gap: 6px; + } + .footer-term__final .pr { color: var(--cyan); } + @media (max-width: 720px) { + .footer-term { font-size: 11.5px; padding: 36px 16px 44px; } + } + + /* ════════════════════════════════════════════════════════════════ + OVERDRIVE FUSED — wordmarks (3 switchable variants) + The body carries data-logo="1|2|3" set on load by reading the + ?logo= URL param (default "1"). Each variant renders inside the + nav-logo slot; only the active one is displayed. + ════════════════════════════════════════════════════════════════ */ + .wm { display: none; align-items: center; } + [data-logo="1"] .wm--1, + [data-logo="2"] .wm--2, + [data-logo="3"] .wm--3 { display: inline-flex; } + + /* Variant 1 — [•] selectools */ + .wm--1 { + gap: 8px; + font-family: var(--font-ui); + font-weight: 800; + font-size: 17px; + color: #fff; + letter-spacing: -0.03em; + } + .wm--1__brackets { + font-family: var(--font-mono); + font-weight: 600; + color: var(--exec-color); + font-size: 16px; + display: inline-flex; + align-items: center; + gap: 3px; + } + .wm--1__brackets::before { content: "["; } + .wm--1__brackets::after { content: "]"; } + .wm--1__brackets .exec-dot { width: 6px; height: 6px; } + + /* Variant 2 — s▌electools (cursor inside the word) */ + .wm--2 { + font-family: var(--font-ui); + font-weight: 800; + font-size: 17px; + color: #fff; + letter-spacing: -0.03em; + gap: 0; + } + .wm--2__pre, + .wm--2__post { display: inline-block; } + .wm--2__caret { + display: inline-block; + width: 0.18em; + height: 0.95em; + background: var(--exec-color); + box-shadow: 0 0 6px var(--exec-glow); + vertical-align: text-bottom; + animation: exec-blink 1.05s steps(2, jump-none) infinite; + margin: 0 1px; + } + + /* Variant 3 — terminal banner art (3-row box-drawing) */ + .wm--3 { + font-family: var(--font-mono); + color: var(--exec-color); + align-items: center; + } + .wm--3__banner { + display: block; + font-size: 5.5px; + line-height: 1; + letter-spacing: 0; + white-space: pre; + text-shadow: 0 0 6px var(--exec-glow); + margin: 0; + user-select: none; + filter: drop-shadow(0 0 2px rgba(34, 211, 238, 0.4)); + } + @media (min-width: 720px) { + .wm--3__banner { font-size: 6.5px; } + } + /* Reveal animation: blocks scan-print on load */ + .wm--3__banner.is-typing { mask-image: linear-gradient(90deg, #000 0%, #000 var(--w, 0%), transparent var(--w, 0%)); -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 var(--w, 0%), transparent var(--w, 0%)); } + + /* Visually-hidden semantic h1 for screen readers across all variants */ + .nav-logo .vh { + position: absolute; + width: 1px; height: 1px; + padding: 0; margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; + } + + /* ── Reduced motion (WCAG AA) ──────────────────────────────────── */ + @media (prefers-reduced-motion: reduce) { + *, *::before, *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } + .reveal { opacity: 1 !important; transform: none !important; } + .nav-progress { display: none; } + .hero::before, .hero::after { animation: none; } + .sim-status[data-state="running"] { animation: none; } + /* Terminal install: kill caret blink and hover lift */ + .terminal-body .caret { animation: none; opacity: 1; } + .terminal-install:hover { transform: none; } + /* Section 1 vignettes: snap to visible, kill glow animation */ + .why-vignette { opacity: 1 !important; transform: none !important; } + .why-vignette.in-view .why-block.is-fix { animation: none; } + .why-vignette__num { position: static !important; } + /* Section 2 bento: snap bars to full width, kill hover transform */ + .bento .bento__bar-fill { width: var(--pct, 70%) !important; transition: none; } + .bento__cell:hover { transform: none; } + /* Section 3 personas: kill rotations */ + .persona, .persona:nth-child(1), .persona:nth-child(2), .persona:nth-child(3) { transform: none !important; } + /* Section 4 paths: snap typing terminal to visible, kill marquee scroll */ + .path--code .path-term__line { opacity: 1 !important; transform: none !important; transition: none !important; } + .path-term__caret { animation: none; opacity: 1; } + .path-marquee__row { animation: none; } + .path:hover { transform: none; } + + /* OVERDRIVE FUSED — execution-pointer atoms: kill all motion */ + .exec-dot { animation: none; box-shadow: 0 0 0 1px var(--exec-glow-soft); } + .exec-caret { animation: none; opacity: 1; } + .exec-scan.in-view::after { animation: none; display: none; } + + /* OVERDRIVE FUSED — wordmarks: kill blink + scan animations */ + .wm--2__caret { animation: none !important; opacity: 1; } + .wm--3__banner.is-typing { mask-image: none !important; -webkit-mask-image: none !important; } + + /* OVERDRIVE FUSED — #faq: kill answer fade-in */ + .repl__q-answer { animation: none !important; } + + /* OVERDRIVE FUSED — #enterprise: snap exhibits visible, freeze ring at 95% */ + .ent-exhibit { opacity: 1 !important; transform: none !important; transition: none !important; } + .ent-exhibit::after { animation: none !important; display: none !important; } + .ent-ring__fill { stroke-dashoffset: 15.71 !important; transition: none !important; } + .ent-version { + border-color: rgba(34, 211, 238, 0.3) !important; + background: rgba(34, 211, 238, 0.05) !important; + color: var(--text) !important; + transition: none !important; + } + .ent-version__check { color: var(--cyan) !important; } + + /* OVERDRIVE FUSED — #see-difference: kill clip-path transition + force show all annotations */ + .diff-pane__layer--fg, .diff-pane__split-line, .diff-pane__split-knob { transition: none !important; } + .diff-anno { + opacity: 1 !important; + transform: none !important; + border-color: rgba(34, 211, 238, 0.35) !important; + background: rgba(34, 211, 238, 0.06) !important; + } + .diff-anno__num { background: var(--exec-color) !important; color: var(--bg) !important; } + + /* OVERDRIVE FUSED — #production: kill auto-play fade */ + .prod-panel__state .prod-panel__body { animation: none !important; } + + /* OVERDRIVE FUSED — #eval: snap report to done, freeze marquee */ + .eval-report__bar .exec-dot { animation: none !important; background: var(--green); } + .eval-metric__bar::after { transition: none !important; } + .eval-report .eval-metric.is-acc .eval-metric__bar::after { width: 100% !important; } + .eval-report .eval-metric.is-lat .eval-metric__bar::after { width: 86% !important; background: linear-gradient(90deg, #fbbf24, #fde68a) !important; } + .eval-report .eval-metric.is-cost .eval-metric__bar::after { width: 12% !important; background: linear-gradient(90deg, var(--green), #86efac) !important; } + .eval-metric__value { opacity: 1 !important; transform: none !important; transition: none !important; } + .eval-report__status { background: rgba(34, 197, 94, 0.12) !important; color: var(--green) !important; border-color: rgba(34, 197, 94, 0.4) !important; } + .eval-marquee__row { animation: none !important; } + + /* OVERDRIVE FUSED — #what: snap terminal lines visible, light all chips */ + .what-term__line { opacity: 1 !important; transform: none !important; transition: none !important; } + .what-term__caret { animation: none !important; opacity: 1; } + .what-stage .what-chip { + border-color: rgba(34, 211, 238, 0.4) !important; + background: rgba(34, 211, 238, 0.05) !important; + color: var(--text) !important; + transition: none !important; + } + .what-stage .what-chip__bullet { + background: var(--exec-color) !important; + box-shadow: 0 0 0 3px var(--exec-glow-soft) !important; + } + .what-stage .what-chip__hint { color: var(--cyan) !important; } + } + + + + + + + + +
+
+
+
+ +

AI agents that are just Python.

+

+ Multi-agent graphs, tool calling, RAG, 50 evaluators, and a drag-drop visual builder. All in one pip install. No DSL to learn. No SaaS to pay for. No vendor to depend on. +

+
+
+ + + + ~/your-project + +
+
+ $pip install selectools +
+
+ +
+ Works with +
+ OpenAI + Anthropic + Gemini + Ollama +
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
152 models
+
4612 tests
+
95% coverage
+
88 examples
+
50 evaluators
+
4 providers
+
v0.20.1
+
+
+ + +
+
+ +

Watch agents work. In real time.

+

Pre-recorded traces from real selectools agents. Routing, tool calls, failover, RAG. No API key needed.

+ +
+ + + + + + + + + + +
+ +
+
+
+
+
+
+
+ Customer Support Router + ready +
+
+
+
+
+
+
Elapsed
+
0.0s
+
+
+
Events
+
0 / 0
+
+
+
Model
+
--
+
+
+
Tokens
+
--
+
+
+
Cost
+
--
+
+
+
+
+
+ + +
+
+ +

A Python framework for production AI agents.

+

One pip install. The whole stack. No DSL, no separate packages, no paid SaaS — your code stays plain Python.

+ +
+ +
+
+ + + + agent.py + ~/selectools $ +
+
from selectools import Agent, toolfrom selectools.rag import HybridRAGfrom selectools.guardrails import PIIGuardrailfrom selectools.audit import AuditLogger @tool()def search(q): return rag.query(q) agent = Agent( tools=[search], rag=HybridRAG("./docs"), guardrails=[PIIGuardrail()], audit=AuditLogger(),)result = agent.run("refund policy?")
+
+ + +
+

what you get

+
+ + Multi-agent graphs + Agent() +
+
+ + Hybrid RAG + HybridRAG +
+
+ + Guardrails + PIIGuardrail +
+
+ + Audit logging + AuditLogger +
+
+ + Tool calling + @tool() +
+
+ + 50 evaluators + tested +
+
+ + Visual builder + /builder/ +
+
+
+
+
+ + +
+
+ +

Three problems every agent team hits.

+

No paid debugger. No SaaS account. No bolt-on libraries. Just open the file, see the fix.

+ +
+ +
+
01
+

Your agent did something — you have no idea what.

@@ -2711,22 +4281,30 @@

Three problems every agent team hits.

- -
+ +

The same pipeline. Less ceremony.

-

A 3-agent workflow: planner → writer → reviewer. One framework wraps it in a DSL. The other stays out of your way.

-
-
-
-
-
-
-
- LangGraph · 25 lines -
-
from langgraph.graph import StateGraph, START, END +

A 3-agent workflow: planner → writer → reviewer. Same outcome — 25 lines of ceremony, or one.

+ +
+
+ ← LangGraph · 25 lines + selectools · 1 line → +
+ +
+ +
+
+
+
+
+
+ LangGraph · 25 lines +
+
from langgraph.graph import StateGraph, START, END from typing_extensions import TypedDict class State(TypedDict): @@ -2746,47 +4324,88 @@

The same pipeline. Less ceremony.

g.add_edge("reviewer", END) app = g.compile() result = app.invoke({"text": "prompt"})
+
-
-
-
-
-
-
-
- selectools · 1 line + + +
+
+
+
+
+
+ selectools · 1 line +
+
from selectools import AgentGraph + +result = AgentGraph.chain(planner, writer, reviewer).run("prompt") + +# That's it. No StateGraph. No TypedDict. +# No add_node, no add_edge, no compile(). +# Just three callables and a chain. + +# Need branching? AgentGraph.router(...) +# Need parallel? AgentGraph.parallel(...) +# Need HITL? yield and resume — no node restart. +# Need to deploy? selectools serve agent.yaml
-
from selectools import AgentGraph +
+ + + + + +
+ +
+ + drag to compare + +
-result = AgentGraph.chain(planner, writer, reviewer).run("prompt")
+ +
+
+ 01 + Plain Python. No StateGraph, no TypedDict, no compile(). +
+
+ 02 + HITL resumes at yield point, not by restarting the node. +
+
+ 03 + Zero extra deps. No langchain-core required. +
+
+ 04 + Deploy with selectools serve agent.yaml.
-
    -
  • Plain Python. No StateGraph, no TypedDict, no compile()
  • -
  • HITL resumes at yield point, not by restarting the node
  • -
  • Zero extra deps. No langchain-core required
  • -
  • Deploy: selectools serve agent.yaml
  • -
- -
+ +

Guardrails in the constructor, not an afterthought.

-

PII redaction, audit logging, and injection defense, configured in one AgentConfig, not bolted on with separate packages.

-
-
-
-
-
-
-
- agent.py -
-
from selectools import Agent, AgentConfig, tool +

PII redaction, audit logging, and injection defense, configured in one AgentConfig. Click any step to inspect what the agent produced.

+ +
+ +
+
+
+
+
+ agent.py +
+
from selectools import Agent, AgentConfig, tool from selectools.providers import OpenAIProvider from selectools.guardrails import GuardrailsPipeline, PIIGuardrail from selectools.audit import AuditLogger, PrivacyLevel @@ -2811,32 +4430,66 @@

Guardrails in the constructor, not an afterthought.

) result = agent.run("Find our refund policy")
-
-
-
-
result.content
-
“Our refund policy allows returns within 30 days...”
-
-
-
result.reasoning
-
“User asked about refund policy → search_docs is the right tool”
+ + +
+

result.trace

+
+ + + + + + +
-
-
result.trace
-
- llm_call - - tool_selection - - tool_execution - - llm_call + +
+
+
result.reasoning
+
“The user is asking about the refund policy. I should search the knowledge base for the current terms before answering.”
+
+ step 1 of 4 + llm: gpt-5-mini + tokens: 124 +
+
+
+
result.tool_calls[0]
+
search_docs(query="refund policy")
+
+ step 2 of 4 + tool: search_docs + guardrails: ✓ +
+
+
+
result.tool_outputs[0]
+
“Returns within 30 days of purchase. Original packaging required. Refund issued to original payment method within 5 business days...”
+
+ step 3 of 4 + screen_tool_output: passed + pii: none +
+
+
+
result.content
+
“Our refund policy allows returns within 30 days of purchase, in original packaging. Refunds go back to your original payment method within 5 business days.”
+
+ step 4 of 4 + tokens: 847 + cost: $0.0012 +
-
-
-
result.usage
-
847 tokens · $0.0012
@@ -2960,12 +4613,92 @@

One install. Everything built in.

Both client and server. Connect to any MCP server, expose your tools as one.

- -
- Enterprise-ready -
SBOM (CycloneDX) · Security audit published · @stable / @beta / @deprecated markers · Python 3.9 to 3.13 · 95% test coverage · 4612 tests
+
+
+
+ + +
+
+ +

Five things your security team will ask for first.

+

Not a checkbox row. Real artifacts: a coverage gauge, a test count, a version matrix, an SBOM, stability markers. Audited and shipped.

+ +
+ +
+ test coverage +
+ +
95%
+
+

Statement coverage on the public API surface.

+
+ + +
+ tests passing +
+ 0 +
+

Unit, integration, and e2e — green on every commit.

+
+ + +
+ python supported +
+ 3.13 + 3.12 + 3.11 + 3.10 + 3.9 +
+

Five major versions, one wheel.

+
+ + +
+ supply chain +
+ +
+

CycloneDX SBOM published with every release. Security audit on file.

+ +
+ api stability +
+ + + @stable + core + + + + @beta + new + + + + @deprecated + 2 minors + +
+

Every public symbol marked. Deprecations stay live for two minor releases.

+
@@ -2976,16 +4709,16 @@

One install. Everything built in.

Test your agents. Not just your code.

LangSmith charges $39/seat/mo for agent evaluation. DeepEval requires a separate install. Selectools ships 50 evaluators. Free, local, built in.

-
-
-
-
-
-
-
- test_agent.py -
-
from selectools.evals import EvalSuite, TestCase +
+ +
+
+
+
+
+ test_agent.py +
+
from selectools.evals import EvalSuite, TestCase suite = EvalSuite(agent=agent, cases=[ TestCase( @@ -3001,32 +4734,58 @@

Test your agents. Not just your code.

# report.accuracy → 1.0 # report.latency_p50 → 142ms # report.total_cost → $0.002
-
-
-
-

30 Deterministic Evaluators

-
- ToolUseToolOrderContainsOutputStructuredJSONPythonSQLPIIInjectionSentimentReadabilityAgentTrajectoryToolEfficiencySemanticSimilarity -
+ + +
+
+ + pytest test_agent.py + running
-
-

20 LLM-as-Judge Evaluators

-
- CorrectnessRelevanceFaithfulnessHallucinationToxicitySafetyCoherenceCompletenessConcisenessBiasFactConsistency +
+
+
+ accuracy + 1.000 +
+ +
+
+
+ latency p50 + 142 ms +
+ +
+
+
+ total cost + $0.0020 +
+
-
-

Infrastructure

-
    -
  • Interactive HTML report with charts
  • -
  • JUnit XML for CI (GitHub Actions, Jenkins)
  • -
  • Regression detection with baseline comparison
  • -
  • A/B testing with PairwiseEval
  • -
+
+ + +
+
+ ToolUseToolOrderToolEfficiencyAgentTrajectoryContainsNotContainsEqualsRegexOutputStructuredJSONJSONSchemaPythonSQLMarkdownXMLYAMLPIIInjectionSentimentReadabilitySemanticSimilarityEditDistanceBLEUROUGETokenCountLatencyCostCardinalityDeterminism + + ToolUseToolOrderToolEfficiencyAgentTrajectoryContainsNotContainsEqualsRegexOutputStructuredJSONJSONSchemaPythonSQLMarkdownXMLYAMLPIIInjectionSentimentReadabilitySemanticSimilarityEditDistanceBLEUROUGETokenCountLatencyCostCardinalityDeterminism +
+
+ CorrectnessRelevanceFaithfulnessHallucinationGroundednessToxicitySafetyBiasCoherenceCompletenessConcisenessFactConsistencyHelpfulnessInstructionFollowContextRelevanceAnswerRelevanceRagFaithfulnessPairwiseEvalRubricScoreCustomJudge + + CorrectnessRelevanceFaithfulnessHallucinationGroundednessToxicitySafetyBiasCoherenceCompletenessConcisenessFactConsistencyHelpfulnessInstructionFollowContextRelevanceAnswerRelevanceRagFaithfulnessPairwiseEvalRubricScoreCustomJudge +
+

Eval report preview

@@ -3377,116 +5136,166 @@

88 examples, all runnable.

-

Frequently asked questions

+

Type a question. Or browse the docs.

-
-
- - What is Selectools? - - -
- Selectools is an open-source Python library for building production-ready AI agents with tool calling, RAG (retrieval-augmented generation), and multi-agent orchestration. It supports OpenAI, Anthropic, Gemini, and Ollama providers with a single unified API. Install with: pip install selectools. -
-
-
- - How is Selectools different from LangChain? - - -
- Selectools uses a single Agent class with native tool calling. No chains, no expression language, no complex abstractions. It includes built-in features that require separate paid services in LangChain: 50 evaluators (vs LangSmith at $39/seat/mo), hybrid RAG search, guardrails, audit logging, multi-agent orchestration, and a visual builder. One pip install, everything included, free. -
-
-
- - What LLM providers does Selectools support? - - -
- Five providers: OpenAI (GPT-4, GPT-5, o-series), Anthropic (Claude), Google Gemini, Ollama (local models), and a FallbackProvider for automatic failover with circuit breaker. Includes pricing data for 152 models. For testing without any API key, use the built-in LocalProvider. -
-
-
- - Does Selectools have a visual builder? - - -
- Yes. Selectools ships a drag-and-drop visual agent builder that runs in the browser with zero installation. Design multi-agent workflows, test with mock or real APIs, and export runnable Python or YAML. Try it now → -
-
-
- - How do I install Selectools? - - -
- pip install selectools. For the visual builder with Starlette server: pip install selectools[serve]. For Chroma/Pinecone vector stores: pip install selectools[rag]. Requires Python 3.9+. -
-
-
- - Does Selectools support streaming? - - -
- Yes. astream() provides token-level async streaming with native tool call support. Tool calls are yielded as structured ToolCall objects alongside text chunks, not mixed into the text stream. -
-
-
- - Does Selectools support RAG? - - -
- Yes. The built-in RAG pipeline includes BM25 keyword search + vector semantic search, reciprocal rank fusion (RRF), cross-encoder reranking, semantic and contextual chunking, and 4 vector store backends (memory, SQLite, Chroma, Pinecone). -
-
-
- - Can I use Selectools with local models? - - -
- Yes. Use the OllamaProvider to run agents with any Ollama-compatible local model (Llama, Mistral, Gemma, etc.). For testing without any API or model, use the built-in LocalProvider stub. -
-
-
- - Does Selectools support multi-agent orchestration? - - -
- Yes. AgentGraph supports directed graph orchestration with conditional routing, parallel fan-out (3 merge policies), and checkpoint-backed state. SupervisorAgent provides 4 coordination strategies: plan-and-execute, round-robin, dynamic routing, and magentic-one. Higher-level patterns include PlanAndExecute, Reflective, Debate, and TeamLead agents. + +
+ + + + +
+ -
-
- - Is Selectools production-ready? - - -
- Yes. 4,612 tests at 95% coverage (including 40 real API evaluations), published security audit, SBOM (CycloneDX 1.6), formal deprecation policy, @stable/@beta markers on every public API, and a compatibility matrix covering Python 3.9 to 3.13. Migration guides for LangChain, CrewAI, AutoGen, and LlamaIndex. Apache-2.0 licensed. + +
+
+ + ? + What is Selectools? + getting-started + +
+ Selectools is an open-source Python library for building production-ready AI agents with tool calling, RAG (retrieval-augmented generation), and multi-agent orchestration. It supports OpenAI, Anthropic, Gemini, and Ollama providers with a single unified API. Install with: pip install selectools. +
+
+ +
+ + ? + How is Selectools different from LangChain? + concepts + +
+ Selectools uses a single Agent class with native tool calling. No chains, no expression language, no complex abstractions. It includes built-in features that require separate paid services in LangChain: 50 evaluators (vs LangSmith at $39/seat/mo), hybrid RAG search, guardrails, audit logging, multi-agent orchestration, and a visual builder. One pip install, everything included, free. +
+
+ +
+ + ? + What LLM providers does Selectools support? + providers + +
+ Five providers: OpenAI (GPT-4, GPT-5, o-series), Anthropic (Claude), Google Gemini, Ollama (local models), and a FallbackProvider for automatic failover with circuit breaker. Includes pricing data for 152 models. For testing without any API key, use the built-in LocalProvider. +
+
+ +
+ + ? + Does Selectools have a visual builder? + concepts + +
+ Yes. Selectools ships a drag-and-drop visual agent builder that runs in the browser with zero installation. Design multi-agent workflows, test with mock or real APIs, and export runnable Python or YAML. Try it now → +
+
+ +
+ + ? + How do I install Selectools? + getting-started + +
+ pip install selectools. For the visual builder with Starlette server: pip install selectools[serve]. For Chroma/Pinecone vector stores: pip install selectools[rag]. Requires Python 3.9+. +
+
+ +
+ + ? + Does Selectools support streaming? + advanced + +
+ Yes. astream() provides token-level async streaming with native tool call support. Tool calls are yielded as structured ToolCall objects alongside text chunks, not mixed into the text stream. +
+
+ +
+ + ? + Does Selectools support RAG? + advanced + +
+ Yes. The built-in RAG pipeline includes BM25 keyword search + vector semantic search, reciprocal rank fusion (RRF), cross-encoder reranking, semantic and contextual chunking, and 4 vector store backends (memory, SQLite, Chroma, Pinecone). +
+
+ +
+ + ? + Can I use Selectools with local models? + providers + +
+ Yes. Use the OllamaProvider to run agents with any Ollama-compatible local model (Llama, Mistral, Gemma, etc.). For testing without any API or model, use the built-in LocalProvider stub. +
+
+ +
+ + ? + Does Selectools support multi-agent orchestration? + advanced + +
+ Yes. AgentGraph supports directed graph orchestration with conditional routing, parallel fan-out (3 merge policies), and checkpoint-backed state. SupervisorAgent provides 4 coordination strategies: plan-and-execute, round-robin, dynamic routing, and magentic-one. Higher-level patterns include PlanAndExecute, Reflective, Debate, and TeamLead agents. +
+
+ +
+ + ? + Is Selectools production-ready? + concepts + +
+ Yes. 4,612 tests at 95% coverage (including 40 real API evaluations), published security audit, SBOM (CycloneDX 1.6), formal deprecation policy, @stable/@beta markers on every public API, and a compatibility matrix covering Python 3.9 to 3.13. Migration guides for LangChain, CrewAI, AutoGen, and LlamaIndex. Apache-2.0 licensed. +
+
+ +
no questions match. try a broader search.
-
+
-