// Our prompts and Astra's reasoning:
// The JSON (scripts/gen_traces.py) has {items}; an item is one network: {label, gif (optional), correct, prompt (blocks // of text, with a number where that many weights are left out), question, weights, quoted, brief (the key sentences of // Astra's answer, a code block, its final answer and confidence, in its order), answer (its whole answer, markdown), // tokens, thinking_tokens, effort, thinking (the headings of its hidden thinking, which is all the API returns of it)}. // One tab per item, a compact card: a replay across its top (`media`, an SVG, with the right answer under it) or an // exchange (`chat`: {user, guess, replies: [{model, says, follows}]}, the user's guess in red where a reply follows it), the // network's animation (or, for a // diffusion model, six images it generates) beside three parts, each with its label: the Prompt (the question in a // sentence, what it rules out, and what comes with it; the whole prompt on "Show the full prompt"), the // Answer (the core of Astra's final answer, its confidence and whether it is right, or the weights it // wrote), and the Reasoning (the key sentences of its reply as steps in a box that scrolls, its bold terms // highlighted; the whole reply on "Read full reasoning"). Marked (between ⦃ ⦄ in the JSON, and // the numbers of `marks` in the rows of weights): where Astra reads the weights, in its answer and in the prompt. The // left / right keys switch the tabs. An item may give its question line (`ask`, `rule`), what came with it (`given`, // for weights that were not given as text), its number of runs instead of token counts, a score to show instead of // right or wrong (`result`), and an episode to play beside it (`play`, played by js/handplay.js). A figure's setup sits in${esc(lines.map((l) => l.slice(indent)).join("\n"))}`;
}
// A markdown table (its lines) -> HTML.
function table(lines) {
const cells = (l) => l.trim().replace(/^\||\|$/g, "").split("|").map((c) => inline(c.trim()));
const rows = lines.filter((l) => !/^[\s|:-]+$/.test(l));
const [head, ...body] = rows.map(cells);
return `| ${c} | `).join("")}
|---|
| ${c} | `).join("")}
${inline(rest)}
` : "")); markNext = !rest; continue; } const head = line.match(/^#+\s*(.*)$/) || line.match(/^(?:\*\*)?([A-Z][A-Za-z ]{2,30}):(?:\*\*)?$/); if (head) { closeList(); out.push(`${html}
`); } } closeList(); closeTable(); if (fence !== null) out.push(pre(fence)); return out.join(""); } const typeset = (el) => { if (window.MathJax && MathJax.typesetPromise) MathJax.typesetPromise([el]).catch(() => {}); }; // The whole prompt: its text, "[n numbers left out]" for the weights, and the lines of weights Astra quotes, with // the quoted numbers marked and, beside each line, where it is (for W1: the cell and channel of its input). function fullPrompt(blocks) { return blocks.map((b) => { if (typeof b === "number") return `
${data.anim ? `