Fix the capture proxy overlap and the who-drives slide
Browse files- assets/{index-Bbx2oP2D.js → index-3N5LkWVC.js} +0 -0
- assets/index-78cT1rtj.js +0 -0
- assets/index-9aq7EliA.js +0 -0
- assets/index-B3w3mWdq.js +0 -0
- assets/index-B79OyQDv.js +0 -0
- assets/index-BDHk57-U.js +0 -0
- assets/index-BNmM1o-f.js +0 -0
- assets/index-BY2oEqQ1.js +0 -0
- assets/index-Bc6DTkhb.js +0 -0
- assets/index-BfrUjWqB.js +0 -0
- assets/index-Bi3QvGw1.js +0 -0
- assets/index-BwFaVWM1.js +0 -0
- assets/index-C8_qArG-.js +0 -0
- assets/index-CGyAmRGA.js +0 -0
- assets/index-CRdwQfQc.js +0 -0
- assets/index-CZEXub1c.js +0 -0
- assets/index-CafAjbxk.js +0 -0
- assets/index-Cat0hfIv.js +0 -0
- assets/index-CnLreNlK.js +0 -0
- assets/index-Cny3hg0n.js +0 -0
- assets/index-Cv1XSF5a.js +0 -0
- assets/index-CzjDNvvq.js +0 -0
- assets/index-D32RywPE.js +0 -0
- assets/index-D5vfjkyj.js +0 -0
- assets/index-D9crLrTR.js +0 -0
- assets/index-DFu22CmO.js +0 -0
- assets/index-DKT5lcVW.js +0 -0
- assets/index-DRfgWPNb.js +0 -0
- assets/index-Dj13ONdE.js +0 -0
- assets/index-DtWIMazP.js +0 -0
- assets/index-Dut9o-_5.js +0 -0
- assets/index-Dxgi0Fr8.js +0 -0
- assets/index-O6tcdK8e.js +0 -0
- assets/index-SygG4YNG.js +0 -0
- assets/index-YTKGXYki.js +0 -0
- assets/index-YgwXpJdI.js +0 -0
- assets/index-b0CEtLKa.js +0 -0
- assets/index-neWit8-C.js +0 -0
- assets/index-sGFO8MxW.js +0 -0
- assets/index-x65b2my4.js +0 -0
- index.html +1 -1
- multi-harness-rl-slides.pdf +2 -2
- multi-harness-rl-slides.pptx +2 -2
- source/scripts/export-deck.mjs +69 -0
- source/src/components/OverflowGuard.tsx +1 -1
- source/src/embeds/d3-capture-proxy.html +1 -1
- source/src/slides/11_RLPrimer.tsx +2 -2
- source/src/slides/12b_WhoDrives.tsx +8 -26
- source/src/slides/18_Proxy.tsx +2 -2
- source/src/slides/23b_Tasks.tsx +2 -2
assets/{index-Bbx2oP2D.js → index-3N5LkWVC.js}
RENAMED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-78cT1rtj.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-9aq7EliA.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-B3w3mWdq.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-B79OyQDv.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-BDHk57-U.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-BNmM1o-f.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-BY2oEqQ1.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-Bc6DTkhb.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-BfrUjWqB.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-Bi3QvGw1.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-BwFaVWM1.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-C8_qArG-.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-CGyAmRGA.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-CRdwQfQc.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-CZEXub1c.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-CafAjbxk.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-Cat0hfIv.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-CnLreNlK.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-Cny3hg0n.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-Cv1XSF5a.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-CzjDNvvq.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-D32RywPE.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-D5vfjkyj.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-D9crLrTR.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-DFu22CmO.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-DKT5lcVW.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-DRfgWPNb.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-Dj13ONdE.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-DtWIMazP.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-Dut9o-_5.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-Dxgi0Fr8.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-O6tcdK8e.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-SygG4YNG.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-YTKGXYki.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-YgwXpJdI.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-b0CEtLKa.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-neWit8-C.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-sGFO8MxW.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
assets/index-x65b2my4.js
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
index.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
| 8 |
name="description"
|
| 9 |
content="RL Environments 101: From 'What Is an Env?' to Training Your Own — a talk by Adithya S Kolavi."
|
| 10 |
/>
|
| 11 |
-
<script type="module" crossorigin src="./assets/index-
|
| 12 |
<link rel="stylesheet" crossorigin href="./assets/index-DlQWIdL0.css">
|
| 13 |
</head>
|
| 14 |
<body>
|
|
|
|
| 8 |
name="description"
|
| 9 |
content="RL Environments 101: From 'What Is an Env?' to Training Your Own — a talk by Adithya S Kolavi."
|
| 10 |
/>
|
| 11 |
+
<script type="module" crossorigin src="./assets/index-3N5LkWVC.js"></script>
|
| 12 |
<link rel="stylesheet" crossorigin href="./assets/index-DlQWIdL0.css">
|
| 13 |
</head>
|
| 14 |
<body>
|
multi-harness-rl-slides.pdf
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d8a176dd3c856a23907e0de6b4b3d4f239c0b24f7acbf5dd3611d0e4b998600f
|
| 3 |
+
size 6326516
|
multi-harness-rl-slides.pptx
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:351415b7127815d959eabd24da2a05756c19a47b0f837e755c98672552c67239
|
| 3 |
+
size 7197238
|
source/scripts/export-deck.mjs
CHANGED
|
@@ -78,6 +78,66 @@ const total = await page.evaluate(() => {
|
|
| 78 |
const count = Number(process.env.SLIDES || total || 35);
|
| 79 |
console.log(`exporting ${count} slides`);
|
| 80 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
const pdfPages = [];
|
| 82 |
const shots = [];
|
| 83 |
for (let i = 0; i < count; i++) {
|
|
@@ -89,6 +149,7 @@ for (let i = 0; i < count; i++) {
|
|
| 89 |
? Promise.resolve()
|
| 90 |
: new Promise((r) => f.addEventListener("load", r, { once: true }))));
|
| 91 |
});
|
|
|
|
| 92 |
pdfPages.push(await page.pdf({
|
| 93 |
width: "1280px", height: "720px", printBackground: true,
|
| 94 |
pageRanges: "1", margin: { top: 0, right: 0, bottom: 0, left: 0 },
|
|
@@ -105,6 +166,14 @@ for (let i = 0; i < count; i++) {
|
|
| 105 |
await browser.close();
|
| 106 |
server.close();
|
| 107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
await mkdir(OUTDIR, { recursive: true });
|
| 109 |
|
| 110 |
// stitch the single-page PDFs into one deck
|
|
|
|
| 78 |
const count = Number(process.env.SLIDES || total || 35);
|
| 79 |
console.log(`exporting ${count} slides`);
|
| 80 |
|
| 81 |
+
// Layout check, run on every slide before it is captured. Two things a rendered
|
| 82 |
+
// deck hides well and a projector shows badly: text wider or taller than the box
|
| 83 |
+
// it sits in, and two pieces of text drawn on top of each other.
|
| 84 |
+
function findLayoutProblems() {
|
| 85 |
+
const visible = (e) => {
|
| 86 |
+
const r = e.getBoundingClientRect();
|
| 87 |
+
const cs = getComputedStyle(e);
|
| 88 |
+
return r.width > 0 && r.height > 0 && r.right > 0 && r.left < 1280 && r.top < 720
|
| 89 |
+
&& cs.visibility !== "hidden" && Number(cs.opacity) > 0.05;
|
| 90 |
+
};
|
| 91 |
+
// only the slide on screen: the drawer and the print view hold text too
|
| 92 |
+
const roots = [...document.querySelectorAll("[data-slide-root]")].filter(visible);
|
| 93 |
+
const root = roots[roots.length - 1];
|
| 94 |
+
if (!root) return ["no slide root found"];
|
| 95 |
+
const els = [...root.querySelectorAll("*")]
|
| 96 |
+
.filter((e) => !e.closest("svg") && e.tagName !== "IFRAME" && visible(e));
|
| 97 |
+
const label = (e) => `"${(e.innerText || e.textContent || "").trim().replace(/\s+/g, " ").slice(0, 50)}"`;
|
| 98 |
+
const out = [];
|
| 99 |
+
for (const e of els) {
|
| 100 |
+
const cs = getComputedStyle(e);
|
| 101 |
+
if (cs.overflowX === "visible" && e.clientWidth > 0 && e.scrollWidth > e.clientWidth + 2 && (e.innerText || "").trim())
|
| 102 |
+
out.push(`spills ${e.scrollWidth - e.clientWidth}px out of its box: ${label(e)}`);
|
| 103 |
+
}
|
| 104 |
+
const leaves = els.filter((e) => [...e.childNodes].some((n) => n.nodeType === 3 && n.textContent.trim()));
|
| 105 |
+
// one rect per rendered line, so a phrase that wraps is not treated as the
|
| 106 |
+
// whole block between its first and last line
|
| 107 |
+
const rects = leaves.map((e) => {
|
| 108 |
+
const range = document.createRange();
|
| 109 |
+
range.selectNodeContents(e);
|
| 110 |
+
return [...range.getClientRects()].filter((r) => r.width > 0 && r.height > 0);
|
| 111 |
+
});
|
| 112 |
+
const hit = (a, b) =>
|
| 113 |
+
Math.min(a.right, b.right) - Math.max(a.left, b.left) > 3 && Math.min(a.bottom, b.bottom) - Math.max(a.top, b.top) > 3;
|
| 114 |
+
for (let i = 0; i < leaves.length; i++) {
|
| 115 |
+
for (let j = i + 1; j < leaves.length; j++) {
|
| 116 |
+
if (leaves[i].contains(leaves[j]) || leaves[j].contains(leaves[i])) continue;
|
| 117 |
+
if (rects[i].some((a) => rects[j].some((b) => hit(a, b))))
|
| 118 |
+
out.push(`text overlaps: ${label(leaves[i])} and ${label(leaves[j])}`);
|
| 119 |
+
}
|
| 120 |
+
}
|
| 121 |
+
// text drawn over a box it does not belong to (a caption running into a code
|
| 122 |
+
// panel, a link under a card), which the text-to-text check above misses
|
| 123 |
+
const boxes = els.filter((e) => {
|
| 124 |
+
const cs = getComputedStyle(e);
|
| 125 |
+
const r = e.getBoundingClientRect();
|
| 126 |
+
const drawn = (cs.backgroundColor !== "rgba(0, 0, 0, 0)" && cs.backgroundColor !== "transparent")
|
| 127 |
+
|| ["Top", "Right", "Bottom", "Left"].every((side) => parseFloat(cs[`border${side}Width`]) > 0);
|
| 128 |
+
return drawn && r.width < 1200 && r.height < 650;
|
| 129 |
+
});
|
| 130 |
+
leaves.forEach((t, i) => {
|
| 131 |
+
for (const bx of boxes) {
|
| 132 |
+
if (bx.contains(t) || t.contains(bx)) continue;
|
| 133 |
+
const b = bx.getBoundingClientRect();
|
| 134 |
+
if (rects[i].some((a) => hit(a, b))) { out.push(`text over a box it is not in: ${label(t)} on ${label(bx)}`); break; }
|
| 135 |
+
}
|
| 136 |
+
});
|
| 137 |
+
return out;
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
const problems = [];
|
| 141 |
const pdfPages = [];
|
| 142 |
const shots = [];
|
| 143 |
for (let i = 0; i < count; i++) {
|
|
|
|
| 149 |
? Promise.resolve()
|
| 150 |
: new Promise((r) => f.addEventListener("load", r, { once: true }))));
|
| 151 |
});
|
| 152 |
+
for (const p of await page.evaluate(findLayoutProblems)) problems.push(`slide ${i + 1}: ${p}`);
|
| 153 |
pdfPages.push(await page.pdf({
|
| 154 |
width: "1280px", height: "720px", printBackground: true,
|
| 155 |
pageRanges: "1", margin: { top: 0, right: 0, bottom: 0, left: 0 },
|
|
|
|
| 166 |
await browser.close();
|
| 167 |
server.close();
|
| 168 |
|
| 169 |
+
if (problems.length) {
|
| 170 |
+
console.log(`\n${problems.length} layout problem(s), fix them before using the export:`);
|
| 171 |
+
for (const p of problems) console.log(` ${p}`);
|
| 172 |
+
} else {
|
| 173 |
+
console.log("\nlayout check: no text spills or overlaps");
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
|
| 177 |
await mkdir(OUTDIR, { recursive: true });
|
| 178 |
|
| 179 |
// stitch the single-page PDFs into one deck
|
source/src/components/OverflowGuard.tsx
CHANGED
|
@@ -45,7 +45,7 @@ export function OverflowGuard({ id, children }: { id: string; children: ReactNod
|
|
| 45 |
}, [id]);
|
| 46 |
|
| 47 |
return (
|
| 48 |
-
<div ref={ref} style={{ position: "absolute", inset: 0 }}>
|
| 49 |
{children}
|
| 50 |
{over && (
|
| 51 |
<>
|
|
|
|
| 45 |
}, [id]);
|
| 46 |
|
| 47 |
return (
|
| 48 |
+
<div ref={ref} data-slide-root style={{ position: "absolute", inset: 0 }}>
|
| 49 |
{children}
|
| 50 |
{over && (
|
| 51 |
<>
|
source/src/embeds/d3-capture-proxy.html
CHANGED
|
@@ -148,7 +148,7 @@
|
|
| 148 |
const stages = [['detect dialect','detect'],['normalise, ids on','normalise'],['record','record']];
|
| 149 |
// stages sit lower in the shorter box
|
| 150 |
stages.forEach((sg, k) => {
|
| 151 |
-
const y = yP +
|
| 152 |
const on = si === IDX[sg[1]];
|
| 153 |
const done = after(sg[1]);
|
| 154 |
s += `<circle cx="${xP+17}" cy="${y-3.5}" r="3.4" fill="${on||done ? cReq : bd}" fill-opacity="${on?1:(done?.5:1)}"/>`;
|
|
|
|
| 148 |
const stages = [['detect dialect','detect'],['normalise, ids on','normalise'],['record','record']];
|
| 149 |
// stages sit lower in the shorter box
|
| 150 |
stages.forEach((sg, k) => {
|
| 151 |
+
const y = yP + 54 + k*13;
|
| 152 |
const on = si === IDX[sg[1]];
|
| 153 |
const done = after(sg[1]);
|
| 154 |
s += `<circle cx="${xP+17}" cy="${y-3.5}" r="3.4" fill="${on||done ? cReq : bd}" fill-opacity="${on?1:(done?.5:1)}"/>`;
|
source/src/slides/11_RLPrimer.tsx
CHANGED
|
@@ -20,7 +20,7 @@ export function RLPrimerSlide() {
|
|
| 20 |
<motion.div key={n}
|
| 21 |
initial={{ opacity: 0, x: -16 }} animate={{ opacity: 1, x: 0 }}
|
| 22 |
transition={{ delay: 0.18 + i * 0.14, type: "spring", damping: 22 }}
|
| 23 |
-
style={{ display: "flex", alignItems: "baseline", gap: 24, padding: "
|
| 24 |
>
|
| 25 |
<span style={{ fontFamily: MONO, fontSize: 34, fontWeight: 800, color: T.emerald, width: 44 }}>
|
| 26 |
{n}
|
|
@@ -30,7 +30,7 @@ export function RLPrimerSlide() {
|
|
| 30 |
))}
|
| 31 |
<motion.div
|
| 32 |
initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.85 }}
|
| 33 |
-
style={{ marginTop:
|
| 34 |
border: `1px solid ${T.border}`, background: T.bgRaised }}
|
| 35 |
>
|
| 36 |
<div style={{ fontSize: 21, color: T.textMuted, lineHeight: 1.6 }}>
|
|
|
|
| 20 |
<motion.div key={n}
|
| 21 |
initial={{ opacity: 0, x: -16 }} animate={{ opacity: 1, x: 0 }}
|
| 22 |
transition={{ delay: 0.18 + i * 0.14, type: "spring", damping: 22 }}
|
| 23 |
+
style={{ display: "flex", alignItems: "baseline", gap: 24, padding: "10px 0" }}
|
| 24 |
>
|
| 25 |
<span style={{ fontFamily: MONO, fontSize: 34, fontWeight: 800, color: T.emerald, width: 44 }}>
|
| 26 |
{n}
|
|
|
|
| 30 |
))}
|
| 31 |
<motion.div
|
| 32 |
initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.85 }}
|
| 33 |
+
style={{ marginTop: 22, padding: "22px 26px", borderRadius: 12,
|
| 34 |
border: `1px solid ${T.border}`, background: T.bgRaised }}
|
| 35 |
>
|
| 36 |
<div style={{ fontSize: 21, color: T.textMuted, lineHeight: 1.6 }}>
|
source/src/slides/12b_WhoDrives.tsx
CHANGED
|
@@ -12,47 +12,29 @@ import { Embed } from "../components/Embed";
|
|
| 12 |
// which is the right order to tell it in: this is how RL normally runs, then one
|
| 13 |
// click shows what a harness does to it. The title carries both halves, so the
|
| 14 |
// exported PDF still makes the point without the click.
|
| 15 |
-
const CSS = `body { zoom:
|
| 16 |
|
| 17 |
export function WhoDrivesSlide() {
|
| 18 |
const { T } = useTheme();
|
| 19 |
return (
|
| 20 |
<SlideShell
|
| 21 |
kicker="The background"
|
| 22 |
-
title="
|
| 23 |
titleSize={38}
|
| 24 |
>
|
| 25 |
<div style={{ position: "absolute", top: 152, left: 60, right: 60 }}>
|
| 26 |
-
<Embed name="d3-who-drives" css={CSS} height={
|
| 27 |
|
| 28 |
<motion.div
|
| 29 |
initial={{ opacity: 0 }}
|
| 30 |
animate={{ opacity: 1 }}
|
| 31 |
transition={{ delay: 0.5 }}
|
| 32 |
-
style={{
|
| 33 |
-
marginTop: 18,
|
| 34 |
-
borderLeft: `3px solid ${T.lavender}`,
|
| 35 |
-
paddingLeft: 22,
|
| 36 |
-
fontSize: 20,
|
| 37 |
-
color: T.text,
|
| 38 |
-
lineHeight: 1.55,
|
| 39 |
-
fontStyle: "italic",
|
| 40 |
-
}}
|
| 41 |
>
|
| 42 |
-
|
| 43 |
-
<span style={{ color: T.lavender }}>harnessed agentic RL</span>
|
| 44 |
-
|
| 45 |
-
<
|
| 46 |
-
style={{
|
| 47 |
-
fontFamily: MONO,
|
| 48 |
-
fontSize: 14,
|
| 49 |
-
color: T.textDim,
|
| 50 |
-
marginTop: 10,
|
| 51 |
-
fontStyle: "normal",
|
| 52 |
-
}}
|
| 53 |
-
>
|
| 54 |
-
Agent Lightning, Microsoft 2026
|
| 55 |
-
</div>
|
| 56 |
</motion.div>
|
| 57 |
</div>
|
| 58 |
</SlideShell>
|
|
|
|
| 12 |
// which is the right order to tell it in: this is how RL normally runs, then one
|
| 13 |
// click shows what a harness does to it. The title carries both halves, so the
|
| 14 |
// exported PDF still makes the point without the click.
|
| 15 |
+
const CSS = `body { zoom: 0.84; }`;
|
| 16 |
|
| 17 |
export function WhoDrivesSlide() {
|
| 18 |
const { T } = useTheme();
|
| 19 |
return (
|
| 20 |
<SlideShell
|
| 21 |
kicker="The background"
|
| 22 |
+
title="Who drives the loop: the trainer or the harness"
|
| 23 |
titleSize={38}
|
| 24 |
>
|
| 25 |
<div style={{ position: "absolute", top: 152, left: 60, right: 60 }}>
|
| 26 |
+
<Embed name="d3-who-drives" css={CSS} height={462} />
|
| 27 |
|
| 28 |
<motion.div
|
| 29 |
initial={{ opacity: 0 }}
|
| 30 |
animate={{ opacity: 1 }}
|
| 31 |
transition={{ delay: 0.5 }}
|
| 32 |
+
style={{ marginTop: 10, maxWidth: 1040, fontSize: 18, color: T.text, lineHeight: 1.5 }}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
>
|
| 34 |
+
Agent Lightning calls this{" "}
|
| 35 |
+
<span style={{ color: T.lavender }}>harnessed agentic RL</span>. The harness owns the loop,
|
| 36 |
+
and the trainer only sees the model’s requests and responses.{" "}
|
| 37 |
+
<span style={{ fontFamily: MONO, fontSize: 14, color: T.textDim }}>Agent Lightning, Microsoft 2026</span>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
</motion.div>
|
| 39 |
</div>
|
| 40 |
</SlideShell>
|
source/src/slides/18_Proxy.tsx
CHANGED
|
@@ -12,12 +12,12 @@ export function ProxySlide() {
|
|
| 12 |
return (
|
| 13 |
<SlideShell kicker="How it works" title="The capture proxy" titleSize={40}>
|
| 14 |
<div style={{ position: "absolute", top: 146, left: 60, right: 60, bottom: 26 }}>
|
| 15 |
-
<Embed name="d3-capture-proxy" css={CSS} height={
|
| 16 |
<motion.div
|
| 17 |
initial={{ opacity: 0 }}
|
| 18 |
animate={{ opacity: 1 }}
|
| 19 |
transition={{ delay: 0.45 }}
|
| 20 |
-
style={{ fontSize:
|
| 21 |
>
|
| 22 |
The proxy probes the engine before it trusts it. An engine that will not return token ids
|
| 23 |
and logprobs still serves the rollout, and the trace comes back marked evaluation only.
|
|
|
|
| 12 |
return (
|
| 13 |
<SlideShell kicker="How it works" title="The capture proxy" titleSize={40}>
|
| 14 |
<div style={{ position: "absolute", top: 146, left: 60, right: 60, bottom: 26 }}>
|
| 15 |
+
<Embed name="d3-capture-proxy" css={CSS} height={448} />
|
| 16 |
<motion.div
|
| 17 |
initial={{ opacity: 0 }}
|
| 18 |
animate={{ opacity: 1 }}
|
| 19 |
transition={{ delay: 0.45 }}
|
| 20 |
+
style={{ fontSize: 18, color: T.textMuted, lineHeight: 1.5, marginTop: 10 }}
|
| 21 |
>
|
| 22 |
The proxy probes the engine before it trusts it. An engine that will not return token ids
|
| 23 |
and logprobs still serves the rollout, and the trace comes back marked evaluation only.
|
source/src/slides/23b_Tasks.tsx
CHANGED
|
@@ -67,13 +67,13 @@ export function TasksSlide() {
|
|
| 67 |
</span>
|
| 68 |
</motion.div>
|
| 69 |
|
| 70 |
-
<Embed name="d3-harbor-task" css={CSS} height={
|
| 71 |
|
| 72 |
<motion.div
|
| 73 |
initial={{ opacity: 0 }}
|
| 74 |
animate={{ opacity: 1 }}
|
| 75 |
transition={{ delay: 0.6 }}
|
| 76 |
-
style={{ fontSize:
|
| 77 |
>
|
| 78 |
<span style={{ color: T.white, fontWeight: 700 }}>
|
| 79 |
Verified by a checker, not judged by a model.
|
|
|
|
| 67 |
</span>
|
| 68 |
</motion.div>
|
| 69 |
|
| 70 |
+
<Embed name="d3-harbor-task" css={CSS} height={392} />
|
| 71 |
|
| 72 |
<motion.div
|
| 73 |
initial={{ opacity: 0 }}
|
| 74 |
animate={{ opacity: 1 }}
|
| 75 |
transition={{ delay: 0.6 }}
|
| 76 |
+
style={{ fontSize: 18, color: T.textMuted, lineHeight: 1.5, marginTop: 10, maxWidth: 1060 }}
|
| 77 |
>
|
| 78 |
<span style={{ color: T.white, fontWeight: 700 }}>
|
| 79 |
Verified by a checker, not judged by a model.
|