feat: map DeepSeek Chat sampling robustness
This commit is contained in:
@@ -0,0 +1,334 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { readFileSync, statSync, writeFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const root = resolve(import.meta.dirname, "..");
|
||||
const paths = {
|
||||
sampling: resolve(
|
||||
root,
|
||||
"src/data/deepseek-v2-lite-chat-sampling.json",
|
||||
),
|
||||
evaluation: resolve(
|
||||
root,
|
||||
"src/data/deepseek-v2-lite-chat-sampling-eval.json",
|
||||
),
|
||||
rerun: resolve(
|
||||
root,
|
||||
"src/data/deepseek-v2-lite-chat-sampling-repro-r0r1.json",
|
||||
),
|
||||
reproduction: resolve(
|
||||
root,
|
||||
"src/data/deepseek-v2-lite-chat-sampling-reproduction.json",
|
||||
),
|
||||
output: resolve(
|
||||
root,
|
||||
"src/data/deepseek-v2-lite-chat-sampling-compact.json",
|
||||
),
|
||||
};
|
||||
|
||||
const readJson = (path) => JSON.parse(readFileSync(path, "utf8"));
|
||||
const sha256 = (path) => createHash("sha256")
|
||||
.update(readFileSync(path))
|
||||
.digest("hex");
|
||||
const artifact = (path) => ({
|
||||
bytes: statSync(path).size,
|
||||
sha256: sha256(path),
|
||||
});
|
||||
const mean = (values) => (
|
||||
values.length
|
||||
? values.reduce((total, value) => total + value, 0) / values.length
|
||||
: null
|
||||
);
|
||||
|
||||
const sampling = readJson(paths.sampling);
|
||||
const evaluation = readJson(paths.evaluation);
|
||||
const reproduction = readJson(paths.reproduction);
|
||||
const samplingArtifact = artifact(paths.sampling);
|
||||
const evaluationArtifact = artifact(paths.evaluation);
|
||||
const rerunArtifact = artifact(paths.rerun);
|
||||
|
||||
if (evaluation.input.sampling_sha256 !== samplingArtifact.sha256) {
|
||||
throw new Error("sampling evaluator input hash contract failed");
|
||||
}
|
||||
if (reproduction.formal.sha256 !== samplingArtifact.sha256) {
|
||||
throw new Error("reproduction formal hash contract failed");
|
||||
}
|
||||
if (reproduction.rerun.sha256 !== rerunArtifact.sha256) {
|
||||
throw new Error("reproduction rerun hash contract failed");
|
||||
}
|
||||
if (
|
||||
reproduction.summary.all_preregistered_fields_exact
|
||||
!== reproduction.summary.cells
|
||||
) {
|
||||
throw new Error("sampling reproduction is not exact");
|
||||
}
|
||||
|
||||
const conditions = sampling.seed_contract.condition_row_order;
|
||||
const edges = Object.keys(
|
||||
sampling.summary.by_source_edge[sampling.sources[0].id],
|
||||
);
|
||||
const edgeLabels = {
|
||||
system_eos: "System on − off · EOS",
|
||||
system_bos: "System on − off · BOS",
|
||||
system_x: "System on − off · x",
|
||||
system_period: "System on − off · 句点",
|
||||
bos_at_s0: "BOS − EOS · system off",
|
||||
bos_at_s1: "BOS − EOS · system on",
|
||||
x_at_s0: "x − EOS · system off",
|
||||
x_at_s1: "x − EOS · system on",
|
||||
period_at_s0: "句点 − EOS · system off",
|
||||
period_at_s1: "句点 − EOS · system on",
|
||||
};
|
||||
|
||||
const evalKey = (sourceId, baseSeed, condition) => (
|
||||
`${sourceId}\0${baseSeed}\0${condition}`
|
||||
);
|
||||
const evaluationByKey = new Map(
|
||||
evaluation.rows.map((row) => [
|
||||
evalKey(row.source_id, row.base_seed, row.condition),
|
||||
row,
|
||||
]),
|
||||
);
|
||||
|
||||
const sourceRows = sampling.sources.map((source) => {
|
||||
const conditionRows = Object.fromEntries(conditions.map((condition) => {
|
||||
const rawSummary = sampling.summary.by_source_condition[
|
||||
source.id
|
||||
][condition];
|
||||
const evalSummary = evaluation.summary.by_source_condition[
|
||||
source.id
|
||||
][condition];
|
||||
const samples = source.runs.map((run) => {
|
||||
const output = run.outputs.find(
|
||||
(candidate) => candidate.condition === condition,
|
||||
);
|
||||
const assessed = evaluationByKey.get(
|
||||
evalKey(source.id, run.base_seed, condition),
|
||||
);
|
||||
if (!output || !assessed) {
|
||||
throw new Error(
|
||||
`sample/evaluation row missing: ${source.id}/${run.base_seed}/${condition}`,
|
||||
);
|
||||
}
|
||||
return {
|
||||
replicate: run.replicate_label,
|
||||
baseSeed: run.base_seed,
|
||||
runSeed: run.run_seed,
|
||||
generatedTokens: output.generated_tokens,
|
||||
hitEos: output.hit_eos,
|
||||
truncated: output.stopped_at_max_new_tokens,
|
||||
trajectoryHash: output.generated_token_ids_sha256,
|
||||
textHash: output.text_sha256,
|
||||
preview: output.text.replace(/\s+/g, " ").trim().slice(0, 220),
|
||||
completionClass: assessed.completion_class,
|
||||
math: assessed.task_evaluation && source.domain === "math"
|
||||
? {
|
||||
predicted: assessed.task_evaluation.predicted_final,
|
||||
gold: assessed.task_evaluation.gold_final,
|
||||
exact: assessed.task_evaluation.fixed_budget_numeric_exact,
|
||||
method: assessed.task_evaluation.extraction_method,
|
||||
}
|
||||
: null,
|
||||
code: assessed.task_evaluation && source.domain === "code"
|
||||
? {
|
||||
ast: assessed.task_evaluation.python_ast_parse,
|
||||
status: assessed.task_evaluation.execution.status,
|
||||
passed: assessed.task_evaluation.fixed_budget_tests_pass,
|
||||
cacheHit: assessed.task_evaluation.execution_cache_hit,
|
||||
}
|
||||
: null,
|
||||
};
|
||||
});
|
||||
return [condition, {
|
||||
samples: rawSummary.samples,
|
||||
naturalEos: rawSummary.natural_eos,
|
||||
truncated: rawSummary.budget_truncated,
|
||||
uniqueTrajectories: rawSummary.unique_generated_token_hashes,
|
||||
greedyInSamples: rawSummary.greedy_full_trajectory_in_sample_set,
|
||||
pairwiseSimilarity: rawSummary.pairwise_token_similarity,
|
||||
generatedTokens: rawSummary.generated_tokens,
|
||||
evaluation: evalSummary,
|
||||
trajectories: samples,
|
||||
}];
|
||||
}));
|
||||
return {
|
||||
id: source.id,
|
||||
domain: source.domain,
|
||||
label: source.label,
|
||||
sourceCharacters: source.source_characters,
|
||||
sourceTokens: source.source_tokens,
|
||||
conditions: conditionRows,
|
||||
edges: Object.fromEntries(edges.map((edge) => [
|
||||
edge,
|
||||
{
|
||||
...sampling.summary.by_source_edge[source.id][edge],
|
||||
evaluation: evaluation.summary.by_source_edge[source.id][edge],
|
||||
},
|
||||
])),
|
||||
};
|
||||
});
|
||||
|
||||
const conditionSummary = Object.fromEntries(conditions.map((condition) => {
|
||||
const sourceConditions = sourceRows.map(
|
||||
(source) => source.conditions[condition],
|
||||
);
|
||||
const assessed = evaluation.summary.by_condition[condition];
|
||||
return [condition, {
|
||||
outputs: assessed.outputs,
|
||||
naturalEos: assessed.natural_eos,
|
||||
truncated: assessed.budget_truncated,
|
||||
meanGeneratedTokens: assessed.mean_generated_tokens,
|
||||
uniqueTrajectoriesAcrossSourceSets: sourceConditions.reduce(
|
||||
(total, row) => total + row.uniqueTrajectories,
|
||||
0,
|
||||
),
|
||||
fullEightWayDiversitySets: sourceConditions.filter(
|
||||
(row) => row.uniqueTrajectories === 8,
|
||||
).length,
|
||||
greedyIncludedSourceSets: sourceConditions.filter(
|
||||
(row) => row.greedyInSamples,
|
||||
).length,
|
||||
math: assessed.math,
|
||||
code: assessed.code,
|
||||
}];
|
||||
}));
|
||||
|
||||
const edgeSummary = Object.fromEntries(edges.map((edge) => {
|
||||
const rows = sourceRows.map((source) => source.edges[edge]);
|
||||
return [edge, {
|
||||
label: edgeLabels[edge],
|
||||
sources: rows.length,
|
||||
meanAlignedSimilarity: mean(rows.map(
|
||||
(row) => row.batch_seed_aligned_similarity.mean,
|
||||
)),
|
||||
meanSymmetricNearestSimilarity: mean(rows.map(
|
||||
(row) => row.symmetric_mean_nearest_neighbor_similarity,
|
||||
)),
|
||||
exactHashIntersections: rows.reduce(
|
||||
(total, row) => total + row.generated_hash_set_intersection,
|
||||
0,
|
||||
),
|
||||
exactHashUnion: rows.reduce(
|
||||
(total, row) => total + row.generated_hash_set_union,
|
||||
0,
|
||||
),
|
||||
naturalEosDeltaRightMinusLeft: rows.reduce(
|
||||
(total, row) => (
|
||||
total + row.natural_eos_count_difference_right_minus_left
|
||||
),
|
||||
0,
|
||||
),
|
||||
}];
|
||||
}));
|
||||
|
||||
const result = {
|
||||
schemaVersion: 1,
|
||||
generatedAt: new Date().toISOString(),
|
||||
contract: {
|
||||
protocolId: sampling.protocol_id,
|
||||
model: sampling.model.repo,
|
||||
revision: sampling.model.revision,
|
||||
checkpointIdentity: sampling.model.checkpoint_identity,
|
||||
conditions,
|
||||
conditionFactors: sampling.generation_contract.conditions,
|
||||
edges,
|
||||
edgeLabels,
|
||||
sources: sampling.sources.length,
|
||||
replicates: sampling.seed_contract.executed_base_seeds.length,
|
||||
baseSeeds: sampling.seed_contract.executed_base_seeds,
|
||||
decode: {
|
||||
doSample: sampling.generation_contract.do_sample,
|
||||
temperature: sampling.generation_contract.temperature,
|
||||
topP: sampling.generation_contract.top_p,
|
||||
topK: sampling.generation_contract.top_k,
|
||||
maxNewTokens: sampling.generation_contract.max_new_tokens,
|
||||
},
|
||||
batchSeedAlignedNotCommonRandomNumbers: (
|
||||
sampling.seed_contract.batch_seed_aligned_not_common_random_numbers
|
||||
),
|
||||
counterfactualBoundary: (
|
||||
sampling.generation_contract.counterfactual_boundary
|
||||
),
|
||||
},
|
||||
headline: {
|
||||
outputs: sampling.summary.outputs,
|
||||
naturalEos: sampling.summary.natural_eos,
|
||||
truncated: sampling.summary.budget_truncated,
|
||||
uniqueTrajectoryHashes: (
|
||||
sampling.summary.unique_generated_token_hashes
|
||||
),
|
||||
firstTwoSeedComparableCells: (
|
||||
sampling.summary.first_two_seeds.comparable_cells
|
||||
),
|
||||
firstTwoSeedDifferentTrajectories: (
|
||||
sampling.summary.first_two_seeds.different_trajectories
|
||||
),
|
||||
promptHashExact: (
|
||||
sampling.source_contract.prompt_hash_audit.exact
|
||||
),
|
||||
promptHashCells: (
|
||||
sampling.source_contract.prompt_hash_audit.cells
|
||||
),
|
||||
greedyIncludedSourceConditionSets: sourceRows.reduce(
|
||||
(total, source) => total + conditions.filter(
|
||||
(condition) => source.conditions[condition].greedyInSamples,
|
||||
).length,
|
||||
0,
|
||||
),
|
||||
sourceConditionSets: sourceRows.length * conditions.length,
|
||||
mathExact: evaluation.summary.math.fixed_budget_exact,
|
||||
mathOutputs: evaluation.summary.math.outputs,
|
||||
mathMajority: evaluation.summary.math.unique_absolute_majority,
|
||||
mathGold: evaluation.summary.math.gold,
|
||||
codePassed: evaluation.summary.code.tests_pass,
|
||||
codeOutputs: evaluation.summary.code.outputs,
|
||||
codeUniqueExecutionKeys: (
|
||||
evaluation.sandbox.unique_code_cache_entries
|
||||
),
|
||||
reproducedCells: (
|
||||
reproduction.summary.all_preregistered_fields_exact
|
||||
),
|
||||
reproductionCells: reproduction.summary.cells,
|
||||
},
|
||||
conditions: conditionSummary,
|
||||
edges: edgeSummary,
|
||||
sources: sourceRows,
|
||||
reproduction: reproduction.summary,
|
||||
artifacts: {
|
||||
sampling: samplingArtifact,
|
||||
evaluation: evaluationArtifact,
|
||||
rerun: rerunArtifact,
|
||||
reproduction: artifact(paths.reproduction),
|
||||
},
|
||||
execution: {
|
||||
generationSeconds: sampling.sources.reduce(
|
||||
(total, source) => total + source.runs.reduce(
|
||||
(sourceTotal, run) => sourceTotal + run.generation_seconds,
|
||||
0,
|
||||
),
|
||||
0,
|
||||
),
|
||||
peakCudaMemoryAllocatedBytes: (
|
||||
sampling.execution.peak_cuda_memory_allocated_bytes
|
||||
),
|
||||
deviceMap: sampling.execution.device_map,
|
||||
transformers: sampling.execution.transformers,
|
||||
torch: sampling.execution.torch,
|
||||
sandbox: evaluation.sandbox,
|
||||
},
|
||||
claimBoundary: [
|
||||
...sampling.claim_boundary,
|
||||
...evaluation.claim_boundary,
|
||||
...reproduction.claim_boundary,
|
||||
],
|
||||
};
|
||||
|
||||
writeFileSync(
|
||||
paths.output,
|
||||
`${JSON.stringify(result, null, 2)}\n`,
|
||||
);
|
||||
console.log(JSON.stringify({
|
||||
output: paths.output,
|
||||
...artifact(paths.output),
|
||||
headline: result.headline,
|
||||
}, null, 2));
|
||||
@@ -1210,14 +1210,14 @@ console.log(JSON.stringify(report, null, 2));
|
||||
const numeric = (text) => Number.parseFloat(text.replaceAll(",", ""));
|
||||
const failures = [];
|
||||
if (!overview.title.includes("为什么转向")) failures.push("专题标题异常");
|
||||
if (overview.sections !== 28 || overview.tocLinks !== 28) failures.push("二十七个编号专题加阅读链的目录结构异常");
|
||||
if (overview.sections !== 29 || overview.tocLinks !== 29) failures.push("二十八个编号专题加阅读链的目录结构异常");
|
||||
if (overview.ledgers !== 24 || overview.waves !== 10) failures.push("二十四张问题账或十次转向结构异常");
|
||||
if (overview.paperLinks !== 60 || overview.branches !== 5 || overview.followups !== 1) failures.push("论文链、旁支或公开后续标记异常");
|
||||
if (overview.labTabs !== 4 || overview.labPanels !== 4) failures.push("四联实验结构异常");
|
||||
if (overview.artifactTabs !== 13 || overview.artifactPanels !== 13 || overview.artifactLayers !== 27) failures.push("真实权重十三联实验结构异常");
|
||||
if (overview.behaviorTabs !== 4 || overview.behaviorPanels !== 4 || overview.behaviorSources !== 16 || overview.behaviorEdges !== 10) failures.push("Chat 行为实验结构异常");
|
||||
if (overview.completionDepthTabs !== 4 || overview.completionDepthPanels !== 4 || overview.hiddenStages !== 29 || overview.routerLayers !== 26) failures.push("Chat 完成度与全深度实验结构异常");
|
||||
if (overview.heroLabs !== "19 个可操作实验") failures.push("DeepSeek 实验总数账异常");
|
||||
if (overview.heroLabs !== "20 个可操作实验") failures.push("DeepSeek 实验总数账异常");
|
||||
if (overview.navLinks !== 20 || home.navLinks !== 20 || mobile.mobileLinks !== 20 || overview.activeNav !== "DeepSeek") failures.push("全站导航未同步 DeepSeek");
|
||||
if (overview.documentOverflow > 1 || mobile.documentOverflow > 1) failures.push("桌面或移动端存在文档级横向溢出");
|
||||
if (capacity.initial.panel !== "capacity" || capacity.initial.total !== "32.1× FFN" || capacity.initial.active !== "1.13× FFN") failures.push("V3 稀疏容量初始账异常");
|
||||
|
||||
@@ -0,0 +1,278 @@
|
||||
import { writeFileSync } from "node:fs";
|
||||
|
||||
const cdpPort = process.env.CDP_PORT ?? "9230";
|
||||
const baseUrl = process.env.SITE_URL ?? "http://127.0.0.1:4327";
|
||||
const pages = await fetch(
|
||||
`http://127.0.0.1:${cdpPort}/json/list`,
|
||||
).then((response) => response.json());
|
||||
const page = pages.find((entry) => entry.type === "page");
|
||||
if (!page) throw new Error(`CDP ${cdpPort} 没有可用页面`);
|
||||
|
||||
const socket = new WebSocket(page.webSocketDebuggerUrl);
|
||||
await new Promise((resolve, reject) => {
|
||||
socket.addEventListener("open", resolve, { once: true });
|
||||
socket.addEventListener("error", reject, { once: true });
|
||||
});
|
||||
|
||||
let nextId = 0;
|
||||
const pending = new Map();
|
||||
const exceptions = [];
|
||||
socket.addEventListener("message", (event) => {
|
||||
const message = JSON.parse(event.data);
|
||||
if (message.id && pending.has(message.id)) {
|
||||
const { resolve, reject } = pending.get(message.id);
|
||||
pending.delete(message.id);
|
||||
if (message.error) reject(new Error(message.error.message));
|
||||
else resolve(message.result);
|
||||
}
|
||||
if (message.method === "Runtime.exceptionThrown") {
|
||||
exceptions.push(
|
||||
message.params.exceptionDetails.exception?.description
|
||||
?? message.params.exceptionDetails.text,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const command = (method, params = {}) => new Promise((resolve, reject) => {
|
||||
const id = ++nextId;
|
||||
pending.set(id, { resolve, reject });
|
||||
socket.send(JSON.stringify({ id, method, params }));
|
||||
});
|
||||
const pause = (milliseconds) => new Promise(
|
||||
(resolve) => setTimeout(resolve, milliseconds),
|
||||
);
|
||||
const evaluate = async (expression) => {
|
||||
const result = await command("Runtime.evaluate", {
|
||||
expression,
|
||||
returnByValue: true,
|
||||
awaitPromise: true,
|
||||
});
|
||||
if (result.exceptionDetails) {
|
||||
throw new Error(
|
||||
result.exceptionDetails.exception?.description
|
||||
?? result.exceptionDetails.text,
|
||||
);
|
||||
}
|
||||
return result.result.value;
|
||||
};
|
||||
const navigate = async (path) => {
|
||||
await command("Page.navigate", { url: `${baseUrl}${path}` });
|
||||
for (let attempt = 0; attempt < 80; attempt += 1) {
|
||||
await pause(100);
|
||||
if (await evaluate("document.readyState === 'complete'")) return;
|
||||
}
|
||||
throw new Error(`${path} 加载超时`);
|
||||
};
|
||||
const screenshot = async (path) => {
|
||||
const result = await command("Page.captureScreenshot", {
|
||||
format: "png",
|
||||
captureBeyondViewport: false,
|
||||
});
|
||||
writeFileSync(path, Buffer.from(result.data, "base64"));
|
||||
};
|
||||
const assert = (condition, message) => {
|
||||
if (!condition) throw new Error(message);
|
||||
};
|
||||
|
||||
await command("Page.enable");
|
||||
await command("Runtime.enable");
|
||||
await command("Emulation.setDeviceMetricsOverride", {
|
||||
width: 1440,
|
||||
height: 1100,
|
||||
deviceScaleFactor: 1,
|
||||
mobile: false,
|
||||
});
|
||||
await navigate("/deepseek/");
|
||||
|
||||
const overview = await evaluate(`(() => {
|
||||
const root = document.querySelector("[data-sampling-lab]");
|
||||
document.documentElement.style.scrollBehavior = "auto";
|
||||
window.scrollTo(0, root.getBoundingClientRect().top + window.scrollY);
|
||||
return {
|
||||
tabs: root.querySelectorAll("[data-sp-tab]").length,
|
||||
panels: root.querySelectorAll("[data-sp-panel]").length,
|
||||
seedBars: root.querySelectorAll("[data-sp-seeds] button").length,
|
||||
conditions: root.querySelectorAll(".condition-overview > div").length,
|
||||
edges: root.querySelectorAll(".edge-overview > div").length,
|
||||
heroLabs: [...document.querySelectorAll(".page-facts > div")]
|
||||
.find((node) => node.querySelector("dt")?.textContent.trim() === "LABS")
|
||||
?.querySelector("dd")?.textContent.trim(),
|
||||
activePanel: root.querySelector("[data-sp-panel]:not([hidden])")
|
||||
?.dataset.spPanel,
|
||||
unique: root.querySelector("[data-sp-unique]").textContent.trim(),
|
||||
eos: root.querySelector("[data-sp-eos]").textContent.trim(),
|
||||
greedy: root.querySelector("[data-sp-greedy]").textContent.trim(),
|
||||
documentOverflow: (
|
||||
document.documentElement.scrollWidth
|
||||
- document.documentElement.clientWidth
|
||||
),
|
||||
};
|
||||
})()`);
|
||||
await pause(300);
|
||||
await screenshot("/tmp/llm-atlas-sampling-desktop.png");
|
||||
|
||||
const trajectorySwitch = await evaluate(`(() => {
|
||||
const root = document.querySelector("[data-sampling-lab]");
|
||||
const source = root.querySelector("[data-sp-source]");
|
||||
const condition = root.querySelector("[data-sp-condition]");
|
||||
source.value = "HumanEval/31";
|
||||
source.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
condition.value = "s1_period";
|
||||
condition.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
const buttons = [...root.querySelectorAll("[data-sp-seeds] button")];
|
||||
buttons.at(-1).click();
|
||||
return {
|
||||
unique: root.querySelector("[data-sp-unique]").textContent.trim(),
|
||||
eos: root.querySelector("[data-sp-eos]").textContent.trim(),
|
||||
greedy: root.querySelector("[data-sp-greedy]").textContent.trim(),
|
||||
seedBars: buttons.length,
|
||||
repeats: buttons.filter((button) => button.classList.contains("repeat")).length,
|
||||
selected: buttons.filter((button) => button.classList.contains("selected")).length,
|
||||
focus: root.querySelector("[data-sp-focus-seed]").textContent.trim(),
|
||||
hash: root.querySelector("[data-sp-focus-hash]").textContent.trim(),
|
||||
};
|
||||
})()`);
|
||||
|
||||
const taskSwitch = await evaluate(`(() => {
|
||||
const root = document.querySelector("[data-sampling-lab]");
|
||||
root.querySelector('[data-sp-tab="tasks"]').click();
|
||||
const condition = root.querySelector("[data-sp-task-condition]");
|
||||
const read = () => ({
|
||||
panel: root.querySelector("[data-sp-panel]:not([hidden])").dataset.spPanel,
|
||||
math: root.querySelector("[data-sp-math-total]").textContent.trim(),
|
||||
code: root.querySelector("[data-sp-code-total]").textContent.trim(),
|
||||
mathCells: root.querySelectorAll("[data-sp-math-cells] article").length,
|
||||
codeCells: root.querySelectorAll("[data-sp-code-cells] article").length,
|
||||
});
|
||||
condition.value = "s1_x";
|
||||
condition.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
const systemX = read();
|
||||
condition.value = "s0_period";
|
||||
condition.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
const period = read();
|
||||
return { systemX, period };
|
||||
})()`);
|
||||
|
||||
const edgeSwitch = await evaluate(`(() => {
|
||||
const root = document.querySelector("[data-sampling-lab]");
|
||||
root.querySelector('[data-sp-tab="edges"]').click();
|
||||
const source = root.querySelector("[data-sp-edge-source]");
|
||||
const edge = root.querySelector("[data-sp-edge]");
|
||||
source.value = "gsm8k/test/1069";
|
||||
source.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
edge.value = "system_eos";
|
||||
edge.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
return {
|
||||
panel: root.querySelector("[data-sp-panel]:not([hidden])").dataset.spPanel,
|
||||
aligned: root.querySelector("[data-sp-edge-aligned]").textContent.trim(),
|
||||
nearest: root.querySelector("[data-sp-edge-nearest]").textContent.trim(),
|
||||
overlap: root.querySelector("[data-sp-edge-overlap]").textContent.trim(),
|
||||
left: root.querySelectorAll("[data-sp-edge-left-set] article").length,
|
||||
right: root.querySelectorAll("[data-sp-edge-right-set] article").length,
|
||||
highlighted: root.querySelectorAll(".two-sets article.overlap").length,
|
||||
};
|
||||
})()`);
|
||||
|
||||
const keyboard = await evaluate(`(() => {
|
||||
const root = document.querySelector("[data-sampling-lab]");
|
||||
const first = root.querySelector('[data-sp-tab="trajectories"]');
|
||||
first.click();
|
||||
first.focus();
|
||||
first.dispatchEvent(new KeyboardEvent("keydown", {
|
||||
key: "ArrowRight",
|
||||
bubbles: true,
|
||||
}));
|
||||
const selected = root.querySelector(
|
||||
'[data-sp-tab][aria-selected="true"]',
|
||||
).dataset.spTab;
|
||||
root.querySelector('[data-sp-tab="reproduction"]').click();
|
||||
return {
|
||||
keyboardSelected: selected,
|
||||
visible: root.querySelector("[data-sp-panel]:not([hidden])")
|
||||
.dataset.spPanel,
|
||||
reproFields: root.querySelectorAll(".repro-fields article").length,
|
||||
};
|
||||
})()`);
|
||||
|
||||
await command("Emulation.setDeviceMetricsOverride", {
|
||||
width: 390,
|
||||
height: 844,
|
||||
deviceScaleFactor: 1,
|
||||
mobile: true,
|
||||
});
|
||||
await navigate("/deepseek/#sampling");
|
||||
const mobile = await evaluate(`(() => {
|
||||
const root = document.querySelector("[data-sampling-lab]");
|
||||
document.documentElement.style.scrollBehavior = "auto";
|
||||
window.scrollTo(0, root.getBoundingClientRect().top + window.scrollY);
|
||||
return {
|
||||
tabs: root.querySelectorAll("[data-sp-tab]").length,
|
||||
seedBars: root.querySelectorAll("[data-sp-seeds] button").length,
|
||||
documentOverflow: (
|
||||
document.documentElement.scrollWidth
|
||||
- document.documentElement.clientWidth
|
||||
),
|
||||
rootOverflow: root.scrollWidth - root.clientWidth,
|
||||
};
|
||||
})()`);
|
||||
await pause(300);
|
||||
await screenshot("/tmp/llm-atlas-sampling-mobile.png");
|
||||
|
||||
assert(overview.tabs === 4, `sampling tabs=${overview.tabs}`);
|
||||
assert(overview.panels === 4, `sampling panels=${overview.panels}`);
|
||||
assert(overview.seedBars === 8, `initial seed bars=${overview.seedBars}`);
|
||||
assert(overview.conditions === 8, `condition rows=${overview.conditions}`);
|
||||
assert(overview.edges === 10, `edge rows=${overview.edges}`);
|
||||
assert(overview.heroLabs?.startsWith("20"), `hero labs=${overview.heroLabs}`);
|
||||
assert(overview.activePanel === "trajectories", `active=${overview.activePanel}`);
|
||||
assert(overview.unique === "8 / 8", `initial unique=${overview.unique}`);
|
||||
assert(overview.eos === "5 / 8", `initial eos=${overview.eos}`);
|
||||
assert(overview.greedy === "NO", `initial greedy=${overview.greedy}`);
|
||||
assert(overview.documentOverflow === 0, `desktop overflow=${overview.documentOverflow}`);
|
||||
|
||||
assert(trajectorySwitch.unique === "2 / 8", `switched unique=${trajectorySwitch.unique}`);
|
||||
assert(trajectorySwitch.eos === "8 / 8", `switched eos=${trajectorySwitch.eos}`);
|
||||
assert(trajectorySwitch.greedy === "YES", `switched greedy=${trajectorySwitch.greedy}`);
|
||||
assert(trajectorySwitch.seedBars === 8, `switched seeds=${trajectorySwitch.seedBars}`);
|
||||
assert(trajectorySwitch.repeats >= 2, `repeat markers=${trajectorySwitch.repeats}`);
|
||||
assert(trajectorySwitch.selected === 1, `selected seeds=${trajectorySwitch.selected}`);
|
||||
assert(trajectorySwitch.focus.startsWith("R7"), `focus=${trajectorySwitch.focus}`);
|
||||
assert(trajectorySwitch.hash.includes("sha256"), `focus hash=${trajectorySwitch.hash}`);
|
||||
|
||||
assert(taskSwitch.systemX.panel === "tasks", `task panel=${taskSwitch.systemX.panel}`);
|
||||
assert(taskSwitch.systemX.math === "7 / 8 PASS", `system x math=${taskSwitch.systemX.math}`);
|
||||
assert(taskSwitch.systemX.code === "8 / 8 PASS", `system x code=${taskSwitch.systemX.code}`);
|
||||
assert(taskSwitch.period.code === "7 / 8 PASS", `period code=${taskSwitch.period.code}`);
|
||||
assert(taskSwitch.period.mathCells === 8, `math cells=${taskSwitch.period.mathCells}`);
|
||||
assert(taskSwitch.period.codeCells === 8, `code cells=${taskSwitch.period.codeCells}`);
|
||||
|
||||
assert(edgeSwitch.panel === "edges", `edge panel=${edgeSwitch.panel}`);
|
||||
assert(edgeSwitch.aligned === "77.3%", `edge aligned=${edgeSwitch.aligned}`);
|
||||
assert(edgeSwitch.nearest === "89.4%", `edge nearest=${edgeSwitch.nearest}`);
|
||||
assert(edgeSwitch.overlap === "1 / 14", `edge overlap=${edgeSwitch.overlap}`);
|
||||
assert(edgeSwitch.left === 8 && edgeSwitch.right === 8, `edge sets=${edgeSwitch.left}/${edgeSwitch.right}`);
|
||||
assert(edgeSwitch.highlighted >= 2, `edge highlights=${edgeSwitch.highlighted}`);
|
||||
|
||||
assert(keyboard.keyboardSelected === "tasks", `keyboard selected=${keyboard.keyboardSelected}`);
|
||||
assert(keyboard.visible === "reproduction", `repro visible=${keyboard.visible}`);
|
||||
assert(keyboard.reproFields === 8, `repro fields=${keyboard.reproFields}`);
|
||||
assert(mobile.tabs === 4 && mobile.seedBars === 8, `mobile controls=${mobile.tabs}/${mobile.seedBars}`);
|
||||
assert(mobile.documentOverflow === 0, `mobile document overflow=${mobile.documentOverflow}`);
|
||||
assert(mobile.rootOverflow === 0, `mobile root overflow=${mobile.rootOverflow}`);
|
||||
assert(exceptions.length === 0, `runtime exceptions: ${exceptions.join(" | ")}`);
|
||||
|
||||
console.log(JSON.stringify({
|
||||
overview,
|
||||
trajectorySwitch,
|
||||
taskSwitch,
|
||||
edgeSwitch,
|
||||
keyboard,
|
||||
mobile,
|
||||
exceptions,
|
||||
screenshots: [
|
||||
"/tmp/llm-atlas-sampling-desktop.png",
|
||||
"/tmp/llm-atlas-sampling-mobile.png",
|
||||
],
|
||||
}, null, 2));
|
||||
|
||||
socket.close();
|
||||
Reference in New Issue
Block a user