dispatch-7b-demo / index.html
hvss's picture
The Dispatcher: Agent Ops routing demo
8969fb7 verified
Raw
History Blame Contribute Delete
13.2 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The Dispatcher: Agent Ops — live routing demo</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<style>
:root {
--bg: #060606; --panel: #101010; --panel2: #161615; --line: #262624;
--ink: #f5f5f3; --ink2: #b9b9b3; --mut: #8a8a85; --acc: #ff5c1c;
--blue: #5da9ff; --green: #43e6c5;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: var(--bg); color: var(--ink); font-family: "Space Grotesk", sans-serif; min-height: 100vh; }
.mono { font-family: "IBM Plex Mono", monospace; }
header { display: flex; justify-content: space-between; align-items: center; padding: 22px 36px; border-bottom: 1px solid var(--line); }
.brand { font-family: "IBM Plex Mono", monospace; font-size: 14px; letter-spacing: 4px; color: var(--ink); }
.brand b { color: var(--acc); }
.links a { font-family: "IBM Plex Mono", monospace; font-size: 12px; letter-spacing: 1px; color: var(--mut); text-decoration: none; margin-left: 22px; border-bottom: 1px dotted var(--line); padding-bottom: 2px; }
.links a:hover { color: var(--ink); border-color: var(--acc); }
.stage { display: grid; grid-template-columns: minmax(320px, 460px) 1fr; gap: 28px; padding: 30px 36px 16px; max-width: 1280px; margin: 0 auto; }
@media (max-width: 900px) { .stage { grid-template-columns: 1fr; } }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; }
.card-h { display: flex; justify-content: space-between; align-items: center; padding: 14px 18px; border-bottom: 1px solid var(--line);
font-family: "IBM Plex Mono", monospace; font-size: 11px; letter-spacing: 3px; color: var(--mut); }
.tagset span { margin-left: 8px; padding: 3px 8px; border: 1px solid var(--line); border-radius: 999px; font-size: 10px; color: var(--ink2); }
.req-body { padding: 20px 20px 22px; font-size: 17px; line-height: 1.55; color: var(--ink2); min-height: 150px; }
.caret { display: inline-block; width: 8px; height: 17px; background: var(--acc); vertical-align: -2px; animation: blink 0.9s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }
.router { display: flex; align-items: center; gap: 14px; padding: 16px 20px; border-top: 1px solid var(--line); }
.router .dot { width: 12px; height: 12px; border-radius: 50%; background: var(--mut); flex: none; }
.router.thinking .dot { background: var(--green); animation: pulse 0.7s ease-in-out infinite; }
.router.done .dot { background: var(--green); }
@keyframes pulse { 50% { box-shadow: 0 0 0 8px rgba(67,230,197,0.15); } }
.router .lbl { font-family: "IBM Plex Mono", monospace; font-size: 12px; letter-spacing: 2px; color: var(--mut); }
.router .lbl b { color: var(--ink); font-weight: 500; }
.plan-body { padding: 16px 18px 18px; min-height: 320px; display: flex; flex-direction: column; gap: 10px; }
.step { display: flex; gap: 14px; align-items: flex-start; background: var(--panel2); border: 1px solid var(--line); border-radius: 10px;
padding: 12px 14px; opacity: 0; transform: translateY(8px); transition: opacity 0.4s, transform 0.4s, border-color 0.4s, box-shadow 0.4s; }
.step.on { opacity: 1; transform: none; }
.step.esc.on { border-color: rgba(255,92,28,0.6); box-shadow: 0 0 24px rgba(255,92,28,0.12); }
.step .n { font-family: "IBM Plex Mono", monospace; font-size: 11px; color: var(--mut); padding-top: 3px; flex: none; }
.step .task { font-size: 14.5px; color: var(--ink2); line-height: 1.45; }
.step .meta { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; align-items: center; }
.chip { font-family: "IBM Plex Mono", monospace; font-size: 10.5px; letter-spacing: 0.5px; padding: 3px 9px; border-radius: 999px; border: 1px solid; }
.chip.tool { color: var(--blue); border-color: rgba(93,169,255,0.45); background: rgba(93,169,255,0.08); }
.chip.small { color: var(--green); border-color: rgba(67,230,197,0.4); background: rgba(67,230,197,0.07); }
.chip.esc { color: var(--acc); border-color: rgba(255,92,28,0.55); background: rgba(255,92,28,0.1); font-weight: 600; }
.chip.par { color: var(--mut); border-color: var(--line); }
.stepcost { font-family: "IBM Plex Mono", monospace; font-size: 10.5px; color: var(--mut); }
.tickers { display: grid; grid-template-columns: 1fr 1fr auto; gap: 28px; align-items: center; max-width: 1280px; margin: 0 auto; padding: 10px 36px 8px; }
@media (max-width: 900px) { .tickers { grid-template-columns: 1fr; gap: 12px; } }
.tick { border: 1px solid var(--line); border-radius: 14px; padding: 16px 22px; background: var(--panel); }
.tick .t-lbl { font-family: "IBM Plex Mono", monospace; font-size: 11px; letter-spacing: 3px; color: var(--mut); margin-bottom: 6px; }
.tick .t-val { font-family: "IBM Plex Mono", monospace; font-size: 34px; font-weight: 600; color: var(--ink); }
.tick.frontier .t-val { color: var(--mut); }
.tick.dispatch { border-color: rgba(255,92,28,0.4); }
.tick.dispatch .t-val { color: var(--acc); }
.tick .t-sub { font-family: "IBM Plex Mono", monospace; font-size: 10.5px; color: var(--mut); margin-top: 4px; }
.save { text-align: center; min-width: 170px; opacity: 0; transform: scale(0.9); transition: opacity 0.4s, transform 0.4s; }
.save.on { opacity: 1; transform: none; }
.save .pct { font-family: "IBM Plex Mono", monospace; font-size: 46px; font-weight: 600; color: var(--acc); }
.save .s-lbl { font-family: "IBM Plex Mono", monospace; font-size: 11px; letter-spacing: 3px; color: var(--mut); }
.controls { display: flex; justify-content: center; align-items: center; gap: 18px; padding: 14px 0 6px; }
button { font-family: "IBM Plex Mono", monospace; font-size: 12px; letter-spacing: 2px; color: var(--ink2); background: var(--panel);
border: 1px solid var(--line); border-radius: 8px; padding: 9px 18px; cursor: pointer; }
button:hover { border-color: var(--acc); color: var(--ink); }
.dots { display: flex; gap: 7px; }
.dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--line); cursor: pointer; }
.dots i.on { background: var(--acc); }
footer { text-align: center; padding: 16px 36px 26px; font-family: "IBM Plex Mono", monospace; font-size: 10.5px; color: #55554f; line-height: 1.8; }
footer a { color: var(--mut); }
</style>
</head>
<body>
<header>
<div class="brand">THE DISPATCHER <b>//</b> AGENT OPS</div>
<nav class="links">
<a href="https://huggingface.co/hvss/Dispatch-7B" target="_blank">MODEL</a>
<a href="https://huggingface.co/hvss/Dispatch-7B-GGUF" target="_blank">GGUF</a>
<a href="https://github.com/hasseneafif/finetuned-llm-dispatcher" target="_blank">GITHUB</a>
</nav>
</header>
<main>
<div class="stage">
<section class="card">
<div class="card-h"><span>INCOMING REQUEST</span><span class="tagset" id="tags"></span></div>
<div class="req-body"><span id="reqtext"></span><span class="caret" id="caret"></span></div>
<div class="router" id="router">
<div class="dot"></div>
<div class="lbl" id="routerlbl">DISPATCH-7B // IDLE</div>
</div>
</section>
<section class="card">
<div class="card-h"><span>EXECUTION PLAN</span><span class="mono" id="plancount"></span></div>
<div class="plan-body" id="plan"></div>
</section>
</div>
<div class="tickers">
<div class="tick frontier">
<div class="t-lbl">FRONTIER MODEL DOES EVERYTHING</div>
<div class="t-val" id="tfront">$0.0000</div>
<div class="t-sub">est. cost per 1,000 requests</div>
</div>
<div class="tick dispatch">
<div class="t-lbl">DISPATCH-7B ROUTES THE WORK</div>
<div class="t-val" id="tdisp">$0.0000</div>
<div class="t-sub">router + cheapest adequate workers</div>
</div>
<div class="save" id="save">
<div class="pct" id="savepct">−0%</div>
<div class="s-lbl">THIS REQUEST</div>
</div>
</div>
<div class="controls">
<button id="btnplay">PAUSE</button>
<div class="dots" id="dots"></div>
<button id="btnnext">NEXT ›</button>
</div>
</main>
<footer>
Every example is an unedited Dispatch-7B output on a held-out task it never saw in training.<br>
Cost model per 1k requests: frontier $3/$15 per MTok · mini-tier $0.15/$0.60 · self-hosted 7B router.
<a href="https://huggingface.co/hvss/Dispatch-7B#evaluation" target="_blank">Full evaluation →</a>
</footer>
<script>
const $ = id => document.getElementById(id);
let EXAMPLES = [], idx = 0, playing = true, timers = [], raf = null;
const money = v => "$" + v.toFixed(4);
const clearTimers = () => { timers.forEach(clearTimeout); timers = []; if (raf) cancelAnimationFrame(raf); };
const after = (ms, fn) => timers.push(setTimeout(fn, ms));
function levelsOf(steps) {
const depth = {};
const get = s => depth[s.id] ??= s.depends_on.length
? 1 + Math.max(...s.depends_on.map(d => get(steps.find(x => x.id === d)))) : 0;
steps.forEach(get);
const lv = [];
steps.forEach(s => (lv[depth[s.id]] ??= []).push(s));
return lv;
}
function animateTicker(el, from, to, ms) {
const t0 = performance.now();
const frame = t => {
const k = Math.min(1, (t - t0) / ms), e = 1 - Math.pow(1 - k, 3);
el.textContent = money(from + (to - from) * e);
if (k < 1) raf = requestAnimationFrame(frame);
};
raf = requestAnimationFrame(frame);
}
function chipFor(a) {
if (a === "small_model") return '<span class="chip small">small_model</span>';
if (a === "escalate:frontier") return '<span class="chip esc">escalate:frontier ⚠</span>';
return `<span class="chip tool">${a}</span>`;
}
function run(i) {
clearTimers();
idx = (i + EXAMPLES.length) % EXAMPLES.length;
const ex = EXAMPLES[idx];
document.querySelectorAll("#dots i").forEach((d, j) => d.classList.toggle("on", j === idx));
$("tags").innerHTML = `<span>${ex.difficulty}</span><span>${ex.condition} catalog</span>`;
$("reqtext").textContent = ""; $("caret").style.display = "inline-block";
$("plan").innerHTML = ""; $("plancount").textContent = "";
$("router").className = "router"; $("routerlbl").innerHTML = "DISPATCH-7B // IDLE";
$("save").classList.remove("on");
$("tfront").textContent = money(0); $("tdisp").textContent = money(0);
// 1. typewriter
const text = ex.request, speed = Math.min(16, 2600 / text.length);
let p = 0;
const type = () => {
$("reqtext").textContent = text.slice(0, ++p);
if (p < text.length) timers.push(setTimeout(type, speed));
else { $("caret").style.display = "none"; plan(); }
};
timers.push(setTimeout(type, 350));
// 2. routing + steps
function plan() {
$("router").className = "router thinking";
$("routerlbl").innerHTML = "DISPATCH-7B // <b>ROUTING…</b>";
after(850, () => {
$("router").className = "router done";
$("routerlbl").innerHTML = `DISPATCH-7B // <b>PLAN READY</b> · ${ex.steps.length} steps · router cost ${money(ex.router_cost)}`;
$("plancount").textContent = `${ex.steps.length} STEPS`;
const lv = levelsOf(ex.steps);
let disp = ex.router_cost, delay = 250;
const totalMs = lv.length * 950 + 400;
animateTicker($("tfront"), 0, ex.baseline_total, totalMs);
const dispEl = $("tdisp");
dispEl.textContent = money(disp);
for (const level of lv) {
const par = level.length > 1;
for (const s of level) {
const el = document.createElement("div");
el.className = "step" + (s.assignee === "escalate:frontier" ? " esc" : "");
el.innerHTML = `<div class="n">${String(s.id).padStart(2, "0")}</div>
<div><div class="task">${s.task}</div>
<div class="meta">${chipFor(s.assignee)}${par ? '<span class="chip par">parallel</span>' : ""}
<span class="stepcost">${s.cost ? "+" + money(s.cost) : "free · runs in harness"}</span></div></div>`;
$("plan").appendChild(el);
const c = s.cost;
after(delay, () => { el.classList.add("on"); disp += c; dispEl.textContent = money(disp); });
}
delay += 950;
}
after(delay + 300, () => {
dispEl.textContent = money(ex.dispatch_total);
$("savepct").textContent = "−" + Math.round(ex.savings_pct) + "%";
$("save").classList.add("on");
if (playing) after(4200, () => run(idx + 1));
});
});
}
}
fetch("examples.json").then(r => r.json()).then(data => {
EXAMPLES = data;
$("dots").innerHTML = data.map(() => "<i></i>").join("");
document.querySelectorAll("#dots i").forEach((d, j) => d.onclick = () => { run(j); });
$("btnnext").onclick = () => run(idx + 1);
$("btnplay").onclick = () => {
playing = !playing;
$("btnplay").textContent = playing ? "PAUSE" : "AUTO ▶";
if (playing) run(idx + 1);
};
run(0);
});
</script>
</body>
</html>