diff --git a/README.md b/README.md index aa0c3ca..bd1eb64 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Website: -Paper and library: +Paper and library: GitHub Pages serves the root of `main`. This is a static website with no build step or backend. `.nojekyll` disables Jekyll processing. @@ -15,10 +15,14 @@ node website/check.mjs python3 -m http.server 4174 --bind 127.0.0.1 ``` +The page shows the paper’s Figure 2 beside a short TL;DR, both benchmark plot +groups, an open booking replay, and an always-visible citation. The coding video +comes before the TL;DR. Copy icons briefly confirm success before fading back. + The homepage is `index.html`; its styles, scripts and paper figures are in `website/assets/`. The main coding video is in `demo/coding/`. The booking replay reads `demo/trace-w4.json`. Preserve the original video and recorded measurements; the checks verify displayed results against those recordings. -Code links point to RCLC. The canonical URL and social preview use the +Code links point to CacheBack. The canonical URL and social preview use the organization website address. diff --git a/demo/index.html b/demo/index.html index 290bc82..69b46c9 100644 --- a/demo/index.html +++ b/demo/index.html @@ -93,7 +93,7 @@

Where should Maya collect her pass on Friday, and what ID shou

@@ -35,11 +35,9 @@

CacheBack

DAP LabColumbia University

The receiver asks for what it needs.

-

CacheBack uses that request to select which internal state gets sent.

-

Our simplest implementation of receiver-conditioning: robust and training-free.

-
- -
-
-

Written messages between agents can lose evidence; passing their entire internal state becomes expensive. Receiver-conditioning lets the receiver describe what it needs, so the sender can select what to pass on. CacheBack is our simplest, robust, training-free implementation.

-

On FanOutQA with Qwen 3 8B, CacheBack sends 75% fewer positions than full-state transfer. Compared with same-size text communication, strict accuracy improves by 14.7 percentage points and median completion is 3.2× faster.

-
-
Read the full abstract -
-

Multi-agent systems distribute large contexts across agents that communicate to solve a task. Text messages are compact but require decoding and may omit evidence the receiving agent needs. Recent latent communication instead transfers KV caches. This avoids text generation and can improve accuracy and latency. However, a full KV cache grows linearly with both the context an individual agent processes, and the number of agents that coordinate together.

-

This raises memory and context costs, often far exceeding available GPU resources and context window sizes. Our key observation is that agents need only send what the receiving agent requires for its local task -- which we call receiver-conditioned communication. The receiver agent passes the sender a small description of its information needs, which serves to filter and compress the sender agent's KV cache.

-

CacheBack is a simple, robust, training-free instance of receiver conditioning based on the sender's attention weights. On FanOutQA, CacheBack with Qwen 3 removes 75% of the state the agent would otherwise receive, improving accuracy by 14.7 percentage points and reducing median task-completion latency by 3.2× relative to text communication. We show comparable improvements across model families that span dense Transformers, Mamba-attention hybrids, and sliding-window attention.

-

A KV cache stores intermediate state from the text a model has processed. Abstract from the published paper, by Rossi et al. CC BY 4.0; emphasis added.

-
-
-
-
-
-
-

How it works

-

The receiver describes what it needs for its next task. CacheBack uses that request to select part of the sender’s internal numerical state, or latent state, to send back.

-
-
-
-

Sender

Select state using
the request

- -

Receiver

Has the next task

-
-
-

CacheBack

-

Our simplest implementation.
Robust and training-free.

-

Uses attention to the receiver’s request to score sender positions, then selects a subset within the message budget.

-
-
-
What crosses the handoff?

CacheBack selects positions using the sender’s attention to the receiver’s request. In the paper’s selected-embedding channel, the corresponding input vectors are sent and the receiver rebuilds its KV cache. A position is not an isolated fact, and an attention score is not a guarantee of relevance. The experiments use matching models; cross-model translation is outside this work. Read the method and limitations.

-
-
-

Results

On FanOutQA, three agents read separate sources and send state to one answering agent. These curves compare accuracy and completion time across message budgets and text-sender sizes.

-
-

Accuracy and completion time

Higher is more accurate. Further left is faster. Each point is a measured setting; lines join the best observed tradeoffs within each method. Text points vary sender size; CacheBack points vary compression or message budget. The receiver stays fixed.

Reading r4, r8, r16: rX means keeping about 1/X of the sender’s sequence positions. For example, r4 keeps 25%, r8 keeps 12.5%, and r16 keeps 6.25%. Larger numbers mean more compression and a smaller message.

-
● ━ CacheBack▲ ┄ Text communication× Question only
-
-
FanOutQA, Qwen 3 8B: CacheBack r4 reaches 55.3% strict accuracy at 192 seconds, compared with 40.7% at 612 seconds for same-size text; weaker settings are also plotted.
Qwen 3: r4 improves strict accuracy from 40.7% to 55.3% and median completion from 612 to 192 seconds.
-
FanOutQA, Nemotron Nano 2 12B: CacheBack r8 reaches 50% accuracy near 102 seconds versus 38.7% near 131 seconds for same-size text. A smaller text sender is faster at lower accuracy.
Nemotron: the benefit also appears in a model combining Mamba and attention. A smaller text sender is faster, but less accurate.
-
-
Repeated handoffs: LongBench v2

On LongBench v2 Easy, four agents read successive sections of a long document. A final receiver answers from the last handoff. Evidence from the beginning must survive the chain.

A relative budget uses the rX fraction above, so message size grows with the sender’s context. A fixed budget caps the number of message positions, as in the labels “32K fixed” and “64K fixed”.

-
● ━ CacheBack · relative budget■ ━ CacheBack · fixed budget▲ ┄ Text× Question only
-
-
LongBench v2 Easy, Qwen 3 8B: both relative and fixed CacheBack budgets include settings faster and more accurate than same-size text. Stronger compression eventually lowers accuracy.
Qwen 3: both message-budget schemes improve the measured tradeoff. More aggressive compression eventually reduces accuracy.
-
LongBench v2 Easy, Nemotron Nano 2 12B: CacheBack r8 reaches 48% accuracy near 133 seconds, while fixed-budget settings show a different tradeoff; smaller text senders can be faster.
Nemotron: a fixed budget caps message positions; a relative budget grows with the material read. Neither denotes total GPU memory.
-
-
-

Redrawn from the paper’s plotting data for Qwen and Nemotron. Each benchmark uses 50 tasks submitted together on eight H100s; completion includes queueing. Accuracy averages three receiver draws. Qwen uses a 0 to 1,000 s time axis, Nemotron 0 to 400 s; each model keeps its scale across benchmarks. Figures 5, 11, and 12 in the paper.

-

About “94% CacheBack”: r16 retains one sender position in sixteen, removing 93.75%. The selected Qwen result above uses r4, or 75% fewer positions. Position reduction is not total GPU memory saved.

-
-
-

Watch the demo

Seven workers help a coordinator fix a Django bug. Compare latent handoffs with written reports.

+

Watch the demo

36 seconds · 4K · Recorded coding task

Fixing a Django bug with seven coding agents

Qwen3-8B produces the patch 4.41× faster with CacheBack than with written reports on this case. Both runs make the same one-line code change and pass all 88 tests.

-
-

Recorded model run

Where should Maya collect her pass on Friday, and what ID should she bring?

Three documents contain the booking, a change of location, and the new desk’s ID rules. The final agent must connect all three.

-
-
-

CacheBack

3.42 s
-

Maya should collect her pass at Harbour Hub on Friday, and she should bring a passport as her ID.

-
Evidence quoted by the model
Evidence: -- "Reference J7 has moved to Harbour Hub." -- "Harbour Hub requires a passport for replacement building pass collections."
-
-
-

Text messages

26.09 s
-

Maya should collect her pass at the assigned desk based on her reference J7, not at the Central Desk. She should check the Friday operations notice using her reference J7 to confirm the exact location. The ID she should bring depends on the desk where she collects her pass. If she is collecting at Harbour Hub, she must bring a passport, as a driving licence is not accepted. The name on the ID must match her booking, and the ID requirements for the specific desk apply.

-
Evidence quoted by the model
Evidence: -- "Maya should collect her pass at the assigned desk based on her reference, not at the Central Desk." -- "She should check the Friday operations notice using her reference J7 to confirm the exact location." -- "If she is collecting at Harbour Hub, a passport is required, and a driving licence is not accepted."
-
-
-

Qwen3-8B · one A100 · r4 · one warm run per method. Times include three handoffs and final answer generation, excluding model loading, tokenization, and warmup. This recording is an example, not a benchmark. Raw recording · Setup

-
Replay the booking handoffs - -
-
-
- +
+
+
Figure 2: sending every agent's full cache exceeds the receiver's context limit. CacheBack sends selected positions and latent steps, leaving room for the receiver's prompt.
Figure 2. Select what the receiver needs, instead of accumulating every sender’s context.
+

TL;DR

Agents can share internal model state instead of writing reports. Sending all of it, however, overwhelms the receiver.

The receiver asks for what it needs. CacheBack uses attention to that request to select which state gets sent. Simple, robust, and training-free.

+
+
+

Results

+
+

FanOutQA

Three senders read separate sources; one receiver answers. Higher is more accurate; left is faster. CacheBack points vary message size; text points vary sender size. rX keeps 1/X of the sender’s positions: r4 keeps 25%.

+
● ━ CacheBack▲ ┄ Text communication× Question only
+
+
FanOutQA, Qwen 3 8B: CacheBack r4 reaches 55.3% strict accuracy at 192 seconds, compared with 40.7% at 612 seconds for same-size text; weaker settings are also plotted.
+
FanOutQA, Nemotron Nano 2 12B: CacheBack r8 reaches 50% accuracy near 102 seconds versus 38.7% near 131 seconds for same-size text. A smaller text sender is faster at lower accuracy.
+

LongBench v2 Easy

Four agents read a long document in sequence, passing state to a final answering agent. Relative budgets (rX) grow with context; fixed budgets (32K, 64K) cap message positions. Stronger compression can reduce accuracy.

+
● ━ CacheBack · relative budget■ ━ CacheBack · fixed budget▲ ┄ Text× Question only
+
+
LongBench v2 Easy, Qwen 3 8B: both relative and fixed CacheBack budgets include settings faster and more accurate than same-size text. Stronger compression eventually lowers accuracy.
+
LongBench v2 Easy, Nemotron Nano 2 12B: CacheBack r8 reaches 48% accuracy near 133 seconds, while fixed-budget settings show a different tradeoff; smaller text senders can be faster.
+
+
+

50 concurrent tasks on 8 H100s; accuracy averaged over three receiver draws. Completion includes queueing. Full setup and results in the paper.

+
+
+
+
-

Quickstart

Bind a sender and receiver to matching models, then pass the receiver’s request to rcc.transfer. CacheBack is the default selector. Continue generation with your model’s native API.

Code and documentation

Local Qwen 3 weights, using Hugging Face or vLLM.
Hosted chat APIs do not expose the required state.

Python
import rcc
+    

Use CacheBack

Install rclc, bind your agents, and pass the receiver’s request.

Code and documentation

Local Qwen 3 weights, using Hugging Face or vLLM.
Hosted chat APIs do not expose the required state.

Python
import rclc
 
-sender = rcc.bind(
+sender = rclc.bind(
     model, tokenizer,
     messages=sender_history, backend="hf",
 )
-receiver = rcc.bind(
+receiver = rclc.bind(
     model, tokenizer,
     messages=receiver_history, backend="hf",
 )
-await rcc.transfer(
+await rclc.transfer(
     sender, receiver,
     "Who owns the Cedar booking?",
 )
-inputs = receiver.pop()

Model, tokenizer, and histories loaded; run in an async function or notebook. Runnable quickstart

-

THE PAPER

Receiver-Conditioned Latent Communication gives 94% CacheBack

Maximillian Rossi, Prajwal Raghunath, Haoqing Xuan, Yusen Zhang, and Eugene Wu.

Cite this work BibTeX
@misc{rossi2026cacheback,
+inputs = receiver.pop()

Model, tokenizer, and histories loaded; run in an async function or notebook. Runnable quickstart

+

THE PAPER

Receiver-Conditioned Latent Communication gives 94% CacheBack

Maximillian Rossi, Prajwal Raghunath, Haoqing Xuan, Yusen Zhang, and Eugene Wu.

Cite this work

@misc{rossi2026cacheback,
   title = {Receiver-Conditioned Latent Communication
            gives 94\% CacheBack},
   author = {Rossi, Maximillian and Raghunath, Prajwal
@@ -194,9 +129,9 @@ 

CacheBack

archivePrefix = {arXiv}, primaryClass = {cs.AI}, url = {https://arxiv.org/abs/2609.32046} -}
+}
- +
diff --git a/website/assets/app.js b/website/assets/app.js index c171406..ee76664 100644 --- a/website/assets/app.js +++ b/website/assets/app.js @@ -1,6 +1,5 @@ if (typeof document !== 'undefined') { const byId = (id) => document.getElementById(id); - byId('cite-link').addEventListener('click', () => { byId('citation').open = true; }); const video = byId('coding-video'); const play = byId('play-demo'); play.hidden = false; @@ -15,11 +14,12 @@ if (typeof document !== 'undefined') { video.addEventListener('play', () => { play.hidden = true; }); document.querySelectorAll('[data-copy]').forEach((button) => { + let reset; button.addEventListener('click', async () => { const content = byId(button.dataset.copy); try { await navigator.clipboard.writeText(content.textContent); - button.textContent = 'Copied'; + button.querySelector('.copy-feedback').textContent = 'Copied'; byId('copy-status').textContent = 'Copied to clipboard.'; } catch { const selection = window.getSelection(); @@ -27,9 +27,12 @@ if (typeof document !== 'undefined') { range.selectNodeContents(content); selection.removeAllRanges(); selection.addRange(range); - button.textContent = 'Text selected'; + button.querySelector('.copy-feedback').textContent = 'Selected'; byId('copy-status').textContent = 'Clipboard unavailable. Text selected; use your device’s copy command.'; } + clearTimeout(reset); + button.classList.add('is-copied'); + reset = setTimeout(() => button.classList.remove('is-copied'), 1800); }); }); } diff --git a/website/assets/figures/communication-overview.webp b/website/assets/figures/communication-overview.webp new file mode 100644 index 0000000..b4d5c54 Binary files /dev/null and b/website/assets/figures/communication-overview.webp differ diff --git a/website/assets/styles.css b/website/assets/styles.css index 47b94f1..247e686 100644 --- a/website/assets/styles.css +++ b/website/assets/styles.css @@ -1,6 +1,6 @@ -@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;450;500;550;600;650;700&family=Instrument+Serif&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;450;500;550;600;650;700&display=swap'); -:root { --paper:#fafafa; --ink:#202828; --muted:#636b6b; --line:#dce3e2; --soft:#f0f5f4; --accent:#bde8e3; --rclc:#0f766e; --text:#995319; --fixed:#795697; --serif:'Instrument Serif',Georgia,serif; --sans:'DM Sans',Arial,sans-serif; } +:root { --paper:#fafafa; --ink:#202828; --muted:#636b6b; --line:#dce3e2; --soft:#f0f5f4; --accent:#bde8e3; --rclc:#0f766e; --text:#995319; --fixed:#795697; --sans:'DM Sans',Arial,sans-serif; } * { box-sizing:border-box; } html { scroll-behavior:smooth; scroll-padding-top:35px; } body { margin:0; background:var(--paper); color:var(--ink); font:16px/1.65 var(--sans); -webkit-font-smoothing:antialiased; } @@ -14,7 +14,6 @@ button:disabled { cursor:default; } :focus-visible { outline:3px solid var(--rclc); outline-offset:5px; } h1,h2,h3,p,figure { margin:0; } h1,h2,h3 { font-weight:500; } -em { font-family:var(--serif); font-style:normal; font-weight:400; } .wrap { width:min(1240px,calc(100% - 112px)); margin-inline:auto; } .site-header { min-height:100px; display:flex; align-items:center; justify-content:space-between; gap:24px; border-bottom:1px solid var(--line); } .brand { display:inline-flex; align-items:center; gap:12px; font-size:21px; letter-spacing:-.7px; font-weight:650; text-decoration:none; white-space:nowrap; } @@ -42,7 +41,6 @@ h1 { font-size:clamp(56px,6vw,84px); font-weight:650; line-height:1.05; letter-s .affiliations img { display:block; height:28px; width:auto; } .hero-intro { font-size:22px; line-height:1.45; letter-spacing:-.4px; } .hero-intro .rclc-emphasis { color:var(--rclc); font-weight:700; } -.hero-description { margin-top:19px; max-width:490px; color:var(--muted); font-size:16px; line-height:1.7; } .hero-actions { display:flex; flex-wrap:wrap; align-items:center; gap:24px; margin-top:29px; } .text-link { font-size:14px; font-weight:500; } .resource-links { display:flex; flex-wrap:wrap; align-items:center; gap:9px; margin-top:31px; font-size:14px; } @@ -57,9 +55,6 @@ strong,b { font-weight:650; } .rclc-emphasis { color:var(--rclc); } .text-emphasis { color:var(--text); } .fixed-emphasis { color:var(--fixed); } -mark { background:var(--rclc); color:#fff; font-weight:700; padding:.08em .22em; -webkit-box-decoration-break:clone; box-decoration-break:clone; } -.contribution { margin-top:15px; font-size:14px; color:var(--muted); } -.contribution strong { color:var(--rclc); } .hero-results { min-width:0; } .hero-results .eyebrow { line-height:1.65; } .chart-context { color:var(--muted); font-size:13px; line-height:1.5; margin-top:9px; max-width:400px; } @@ -95,60 +90,26 @@ mark { background:var(--rclc); color:#fff; font-weight:700; padding:.08em .22em; .chart-axis span:nth-child(2) { left:50%; } .chart-axis span:nth-child(3) { left:100%; } -.abstract-section { display:grid; grid-template-columns:1fr 2.1fr; gap:60px; padding-block:64px; border-top:1px solid var(--line); } -.abstract-label h2 { margin:0 0 18px; } -.tldr { font-size:18px; line-height:1.75; } +.abstract-section { display:grid; grid-template-columns:1.4fr 1fr; align-items:center; gap:48px; padding-block:64px; border-top:1px solid var(--line); } +.tldr { font-size:17px; line-height:1.75; } +.tldr h2 { margin-bottom:18px; } +.overview-figure img { width:100%; height:auto; display:block; } +.overview-figure figcaption { color:var(--muted); font-size:12px; margin-top:18px; } .tldr p+p { margin-top:18px; } .tldr strong { color:var(--rclc); } -.full-abstract { margin-top:26px; border-top:1px solid var(--line); padding-top:18px; } -.full-abstract>summary { color:var(--rclc); font-weight:600; } -.full-abstract[open]>summary { margin-bottom:24px; } -.abstract-text p { margin-bottom:18px; line-height:1.8; } -.abstract-text strong { font-weight:700; } -.abstract-text .rclc-emphasis { color:var(--rclc); text-decoration:underline; text-decoration-color:#79c9c1; text-decoration-thickness:3px; text-underline-offset:4px; } -.abstract-text .result-highlight { background:var(--rclc); color:#fff; padding:.08em .3em; -webkit-box-decoration-break:clone; box-decoration-break:clone; } -.abstract-text .abstract-note { color:var(--muted); font-size:12px; margin-bottom:0; line-height:1.65; } .paper-curves { margin-top:30px; } .curves-heading { max-width:810px; } .curves-heading h3 { font-size:27px; margin-bottom:12px; } .curves-heading p { color:var(--muted); font-size:15px; } -.curves-heading p+p { margin-top:16px; } .curve-legend { display:flex; flex-wrap:wrap; gap:10px 24px; font-size:13px; margin-block:23px 5px; } .curve-grid { display:grid; grid-template-columns:1fr 1fr; gap:34px; } .curve-grid figure { min-width:0; } .curve-grid img { width:100%; height:auto; display:block; } -.curve-grid figcaption { border-top:1px solid var(--line); padding-top:15px; color:var(--muted); font-size:13px; } -.curve-grid figcaption strong { color:var(--ink); } .chain-results { margin-top:32px; border-block:1px solid var(--line); padding:20px 0; } -.chain-results>summary { font-size:20px; } -.chain-results[open]>summary { margin-bottom:22px; } -.curve-caption,.compression-note { color:var(--muted); font-size:12px; margin-top:26px; } -.compression-note { border-left:2px solid #9acac5; padding-left:16px; max-width:900px; } +.curve-caption { color:var(--muted); font-size:12px; margin-top:26px; } .section { padding-block:64px; border-top:1px solid var(--line); } -.section-heading { display:grid; grid-template-columns:1fr 1fr; column-gap:90px; align-items:start; } h2 { font-size:36px; line-height:1.2; letter-spacing:-1.1px; } -.section-heading>p:last-child { color:var(--muted); max-width:450px; margin-bottom:3px; } h3 { font-size:20px; letter-spacing:-.5px; } -.method-heading { align-items:start; } -.method-heading>p:last-child { padding-top:4px; } -.method-heading strong { color:var(--ink); } -.handoff { margin-top:28px; border:1px solid var(--line); border-radius:16px; overflow:hidden; background:#fff; } -.handoff-flow { display:grid; grid-template-columns:1fr 1.6fr 1fr; align-items:center; gap:40px; padding:34px 48px; } -.handoff-party { text-align:center; } -.handoff-party h3 { font-size:32px; letter-spacing:-1px; } -.handoff-party p { margin-top:4px; font-size:14px; color:var(--muted); } -.handoff-receiver h3 { color:var(--rclc); } -.handoff-messages { display:grid; gap:27px; font-size:15px; font-weight:600; text-align:center; } -.handoff-messages span { font-size:11px; font-weight:450; margin-right:7px; } -.handoff-messages i { display:block; position:relative; height:2px; margin-top:10px; background:currentColor; } -.handoff-messages i::after { content:""; position:absolute; width:9px; height:9px; top:-3.5px; border-top:2px solid; border-right:2px solid; } -.handoff-request i::after { left:0; transform:rotate(-135deg); } -.handoff-state { color:var(--rclc); } -.handoff-state i::after { right:0; transform:rotate(45deg); } -.selector-note { display:grid; grid-template-columns:.75fr 1.15fr 1.6fr; gap:32px; align-items:center; padding:27px 36px; background:var(--rclc); color:#fff; } -.selector-note h3 { font-size:28px; letter-spacing:-.8px; } -.selector-note strong { font-size:16px; } -.selector-note p:last-child { font-size:14px; color:#e1f3f1; } .technical { border-top:1px solid var(--line); border-bottom:1px solid var(--line); margin-top:32px; padding:15px 0; font-size:14px; } summary { font-weight:500; } .technical p { color:var(--muted); max-width:960px; margin-top:17px; } @@ -156,7 +117,6 @@ summary { font-weight:500; } .demo-heading { display:grid; grid-template-columns:1fr 1fr; align-items:end; gap:85px; margin-bottom:32px; } .demo-heading p { color:var(--muted); max-width:460px; } .recorded-demo { background:#fff; border:1px solid var(--line); border-radius:14px; overflow:hidden; } -.recorded-demo+.recorded-demo { margin-top:48px; } .coding-demo video { display:block; width:100%; height:auto; aspect-ratio:16/9; background:#f4f5f5; border-top:1px solid var(--line); } .coding-demo .demo-evidence { margin-top:12px; } .coding-demo .demo-evidence p { margin-top:12px; max-width:100ch; } @@ -168,33 +128,12 @@ summary { font-weight:500; } .demo-description h3 { font-size:28px; margin:7px 0 10px; } .demo-description p { color:var(--muted); font-size:14px; max-width:74ch; } .demo-description .demo-type { font-size:11px; font-weight:650; text-transform:uppercase; letter-spacing:.09em; color:var(--rclc); } -.demo-outcomes { display:grid; grid-template-columns:1fr 1fr; padding:0 30px 26px; gap:30px; } -.demo-outcome { min-width:0; border-top:2px solid #67726b; padding-top:18px; } -.demo-outcome:first-child { border-color:var(--rclc); } -.demo-outcome header { display:flex; align-items:baseline; justify-content:space-between; flex-wrap:wrap; gap:8px; margin-bottom:16px; } -.demo-outcome h4 { margin:0; font-size:16px; font-weight:650; } -.demo-outcome:first-child h4,.demo-outcome:first-child .outcome-time { color:var(--rclc); } -.outcome-time { font-size:23px; font-weight:600; font-variant-numeric:tabular-nums; } -.demo-outcome blockquote { margin:0; font-size:15px; line-height:1.75; } .demo-evidence { margin-top:18px; color:var(--muted); font-size:12px; } .demo-evidence>div { white-space:pre-wrap; margin-top:12px; } -.demo-replay { border-top:1px solid var(--line); } -.demo-replay>summary { display:flex; align-items:center; justify-content:center; gap:16px; padding:28px 30px; background:var(--rclc); color:#fff; font-size:24px; font-weight:700; line-height:1.3; list-style:none; } -.demo-replay>summary::-webkit-details-marker { display:none; } -.demo-replay>summary svg { flex-shrink:0; } -.demo-replay>summary:hover { background:#fff; color:var(--rclc); } -.demo-replay>summary:focus-visible { outline:3px solid var(--ink); outline-offset:-6px; } .demo-replay-link { padding:20px 30px; } .demo-window { border-top:1px solid var(--line); background:#fff; } iframe { display:block; width:100%; height:815px; border:0; background:#fff; } .demo-caption { color:var(--muted); font-size:12px; padding:17px 30px; border-top:1px solid var(--line); } -.upcoming-demos:not([hidden]) { display:grid; grid-template-columns:1fr 1fr; gap:24px; margin-top:28px; } -.demo-slot { border:1px solid var(--line); border-radius:14px; overflow:hidden; } -.demo-slot-surface { aspect-ratio:16/9; min-height:250px; display:flex; flex-direction:column; align-items:flex-start; justify-content:flex-end; padding:28px; background:#f2f4f0; } -.demo-slot-surface>.mono { margin-bottom:auto; color:#758172; } -.demo-slot-surface h3 { font-size:22px; letter-spacing:-.4px; color:#556151; } -.demo-slot-surface p { color:var(--muted); font-size:14px; margin-top:7px; } -.results-note { color:var(--muted); font-size:12px; margin-top:21px; } .code-section { background:var(--soft); border-block:1px solid var(--line); padding:75px 0; } .code-layout { display:grid; grid-template-columns:.9fr 1.1fr; gap:90px; align-items:center; } .code-layout h2 { margin:0 0 20px; } @@ -203,26 +142,21 @@ iframe { display:block; width:100%; height:815px; border:0; background:#fff; } .code-layout .code-note { font-size:12px; margin-top:23px; } .code-card { background:#162c2c; color:#e8f3f2; border-radius:12px; overflow:hidden; min-width:0; } .code-bar { display:flex; align-items:center; justify-content:space-between; gap:10px; border-bottom:1px solid #345151; padding:12px 24px; color:#b6cdcb; font-size:12px; } -.copy-button { border:1px solid var(--line); background:transparent; border-radius:3px; padding:5px 10px; font-size:12px; } +.copy-button { border:0; background:transparent; border-radius:3px; padding:5px 10px; font-size:12px; } .copy-button:hover { background:var(--accent); } .code-card .copy-button { border:0; border-radius:7px; background:#2d4c4b; color:#e8f3f2; padding:6px 11px; } .code-card .copy-button:hover { background:#e8f3f2; color:#162c2c; } .code-card pre { padding:22px 24px 18px; line-height:1.65; } -.code-keyword { color:#bacafa; } -.code-function { color:#8bd9d1; } -.code-string { color:#e6ce99; } .code-focus { display:block; background:#214442; border-left:2px solid #8bd9d1; margin:15px -24px 0; padding:12px 22px; } pre { margin:0; padding:23px; overflow:auto; font:13px/1.85 'SFMono-Regular',Consolas,monospace; tab-size:2; } .snippet-note { font-size:12px; line-height:1.65; color:#adc7c4; padding:0 24px 21px; } .snippet-note a { display:block; margin-top:8px; color:#e8f3f2; } .paper-section { display:grid; grid-template-columns:1.05fr .95fr; gap:80px; align-items:start; } .paper-section h2 { font-size:33px; margin:19px 0; letter-spacing:-1px; } -.paper-section p:not(.eyebrow) { font-size:13px; color:var(--muted); } .citation { border-block:1px solid var(--line); padding:18px 0; margin-top:38px; min-width:0; } -.citation summary { font-size:14px; } -.citation summary>span { float:right; color:var(--muted); font-size:12px; } +.citation h3 { font-size:18px; } .citation pre { padding:18px 0 0; font-size:12px; } -.citation button { margin-top:16px; } +.citation button { margin-top:12px; } .site-footer { padding:27px 0; border-top:1px solid var(--line); display:flex; align-items:center; justify-content:space-between; gap:20px; color:var(--muted); font-size:12px; } .site-footer .brand { color:var(--ink); font-size:17px; } .sr-only { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; } @@ -245,7 +179,6 @@ body { zoom:.85; } .hero-results { width:100%; max-width:600px; } .abstract-section { grid-template-columns:1fr; gap:28px; padding-block:45px; } -.abstract-label h2 { margin-bottom:13px; } .curve-grid { grid-template-columns:1fr; gap:30px; } .site-header { min-height:80px; } .site-header nav { gap:19px; } @@ -254,17 +187,11 @@ body { zoom:.85; } h1 { font-size:72px; } .section { padding-block:60px; } .section-heading,.demo-heading { grid-template-columns:1fr; gap:19px; } -.section-heading>p:last-child { max-width:none; } -.handoff-flow { gap:24px; padding:35px 24px; } -.selector-note { grid-template-columns:1fr 2fr; gap:10px 24px; padding:25px; } -.selector-note h3 { grid-row:span 2; align-self:start; } -.selector-note p:last-child { grid-column:2; } .code-layout,.paper-section { grid-template-columns:1fr; gap:30px; } .code-layout>div>p:not(.eyebrow) { max-width:none; } .citation { margin-top:0; } iframe { height:890px; } .site-footer>span { display:none; } -.upcoming-demos:not([hidden]) { grid-template-columns:1fr; } } @media(max-width:520px) { .hero-authors ul { font-size:17px; gap:4px 17px; } @@ -279,26 +206,14 @@ iframe { height:890px; } h1 { font-size:56px; letter-spacing:-2px; } .hero-subtitle { font-size:23px; } .hero-intro { font-size:21px; } -.hero-description { font-size:16px; } .hero-actions { gap:20px; } .resource-links { gap:8px; } .resource-links a { padding-inline:12px; } h2 { font-size:32px; } -.handoff-flow { grid-template-columns:1fr 1.5fr 1fr; gap:12px; padding:30px 16px; } -.handoff-party h3 { font-size:20px; letter-spacing:-.4px; } -.handoff-party p { font-size:12px; line-height:1.5; } -.handoff-messages { font-size:12px; gap:24px; } -.handoff-messages span { display:none; } -.selector-note { grid-template-columns:1fr; padding:24px; gap:10px; } -.selector-note h3 { grid-row:auto; } -.selector-note p:last-child { grid-column:auto; } .demo-section { padding-top:51px; } -.demo-outcomes { grid-template-columns:1fr; gap:26px; padding:0 20px 24px; } -.demo-replay>summary { padding:24px 20px; gap:12px; font-size:21px; } .demo-replay-link { padding-inline:20px; } .demo-caption { padding:17px 20px; } .demo-description { flex-direction:column; gap:18px; padding:22px 20px; } -.demo-slot-surface { min-height:220px; padding:24px; } .code-section { padding-block:50px; } .paper-section h2 { font-size:32px; } .site-footer { flex-wrap:wrap; font-size:12px; } @@ -308,3 +223,14 @@ h2 { font-size:32px; } html { scroll-behavior:auto; } *,*::before,*::after { transition:none!important; animation:none!important; } } + +.code-keyword { color:#bacafa; } +.code-function { color:#8bd9d1; } +.code-string { color:#e6ce99; } + +.copy-button { position:relative; display:inline-grid; place-items:center; min-width:72px; min-height:36px; } +.copy-icon,.copy-feedback { grid-area:1/1; transition:opacity .6s ease; } +.copy-feedback { opacity:0; } +.is-copied .copy-icon { opacity:0; } +.is-copied .copy-feedback { opacity:1; } +@media(prefers-reduced-motion:reduce) { .copy-icon,.copy-feedback { transition:none; } } diff --git a/website/check.mjs b/website/check.mjs index 9eec915..09c0af6 100644 --- a/website/check.mjs +++ b/website/check.mjs @@ -18,11 +18,11 @@ assert.equal((html.match(//); assert.match(html, /name="viewport"/); assert.match(html, /CacheBack \|/); -const sectionOrder = ['result-summary', 'abstract', 'idea', 'results', 'demo', 'code', 'paper']; +const sectionOrder = ['result-summary', 'demo', 'abstract', 'results', 'booking-demo', 'code', 'paper']; sectionOrder.slice(1).forEach((id, i) => { assert.ok(html.indexOf(`id="${sectionOrder[i]}"`) < html.indexOf(`id="${id}"`), `Section order: ${id}`); }); -assert.equal((html.match(/<img src="website\/assets\/figures\//g) || []).length, 4); +assert.equal((html.match(/<img src="website\/assets\/figures\//g) || []).length, 5); for (const [, url] of html.matchAll(/(?:href|src|poster)="([^"]+)"/g)) { if (/^(https:|data:)/.test(url)) continue; @@ -62,7 +62,6 @@ const speedups = [...html.matchAll(/<strong class="speedup">([\d.]+)× faster<\/ assert.deepEqual(gains, Object.values(data.models).map(m => Number(((m.cache.accuracy - m.text.accuracy) * 100).toFixed(1)))); assert.deepEqual(speedups, Object.values(data.models).map(m => Number((m.text.seconds / m.cache.seconds).toFixed(1)))); assert.doesNotMatch(html, /name="model"/); -assert.match(html, /This recording is an example, not a benchmark/); assert.match(html, /93\.75% removed/); assert.match(html, /loading="lazy" sandbox="allow-scripts allow-same-origin"/); assert.match(css, /prefers-reduced-motion:reduce/); @@ -70,18 +69,12 @@ assert.match(css, /:focus-visible/); assert.match(html, /id="bibtex"/); assert.match(html, /<iframe[^>]+src="demo\/index\.html\?v=fit-3"/); assert.match(readFileSync(resolve(project, 'demo/index.html'), 'utf8'), /fetch\("trace-w4\.json"\)/); -const recording = JSON.parse(readFileSync(resolve(project, 'demo/trace-w4.json'), 'utf8')).cases[0]; -const plain = text => text.replace(/<[^>]+>/g, '').replace(/>/g, '>').replace(/</g, '<').replace(/&/g, '&').replace(/\s+/g, ' ').trim(); -assert.ok(html.includes(`<h3 id="booking-title">${recording.question}</h3>`)); -for (const method of ['rclc', 'text']) { - const [answer, ...evidence] = recording[method].answer.text.split('\n\n'); - for (const [part, tag, expected] of [['answer', 'p', answer], ['evidence', 'div', evidence.join('\n\n')]]) { - const displayed = html.match(new RegExp(`<${tag} id="demo-${method}-${part}">([\\s\\S]*?)</${tag}>`)); - assert.ok(displayed, `Missing recorded ${method} ${part}`); - assert.equal(plain(displayed[1]), plain(expected.replace(/\*\*/g, '')), `Preserve the recorded ${method} ${part}`); - } - assert.ok(html.includes(`id="demo-${method}-time">${recording[method].seconds.toFixed(2)} s</span>`), `Measured ${method} completion time`); -} +// The booking record is rendered by the embedded replay, not duplicated in the page. +const replay = readFileSync(resolve(project, 'demo/index.html'), 'utf8'); +assert.match(replay, /trace-w4\.json/); +assert.match(html, /aria-label="Interactive booking demo"/); +assert.doesNotMatch(html, /Recorded model run|demo-outcomes|hero-description|class="contribution"/); +for (const label of ['Copy code', 'Copy citation']) assert.ok(html.includes(`aria-label="${label}"`)); const coding = JSON.parse(readFileSync(resolve(project, 'demo/coding/evidence.json'), 'utf8')).arms; assert.ok(html.indexOf('id="coding-demo"') < html.indexOf('id="booking-demo"'), 'Coding video is the main demo');