Add Live performance lab and benchmarks

Measure framework and provider latency, enforce fidelity and cleanup gates, and publish reproducible results on the dev-only Live Lab.\n\nAI-assisted: OpenAI Codex.
This commit is contained in:
Paul Bakaus
2026-07-12 17:55:10 -07:00
parent 2106a2881f
commit 02b1040280
28 changed files with 3096 additions and 58 deletions
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env node
import { execFileSync } from 'node:child_process';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const iterations = Math.max(1, Number(arg('--iterations') || 5));
const fixture = arg('--fixture') || 'vite8-react-plain';
const metricsFile = path.join(os.tmpdir(), 'impeccable-live-control-' + process.pid + '.jsonl');
try {
for (let index = 0; index < iterations; index += 1) {
execFileSync('bun', ['run', 'test:live-e2e'], {
cwd: root,
stdio: 'ignore',
timeout: 120_000,
env: {
...process.env,
IMPECCABLE_E2E_ONLY: fixture,
IMPECCABLE_E2E_SCENARIOS: 'progressive',
IMPECCABLE_E2E_METRICS_FILE: metricsFile,
},
});
}
const rows = fs.readFileSync(metricsFile, 'utf-8').trim().split('\n').filter(Boolean).map(JSON.parse);
console.log(JSON.stringify({
fixture,
iterations: rows.length,
measuredAt: new Date().toISOString(),
acceptToPicking: summarize(rows.map((row) => row.acceptToPickingMs)),
nextGoToPickup: summarize(rows.map((row) => row.nextGoToPickupMs)),
samples: rows,
}, null, 2));
} finally {
try { fs.unlinkSync(metricsFile); } catch {}
}
function summarize(values) {
const sorted = [...values].sort((a, b) => a - b);
return {
medianMs: percentile(sorted, 0.5),
p95Ms: percentile(sorted, 0.95),
minMs: sorted[0],
maxMs: sorted.at(-1),
};
}
function percentile(sorted, p) {
const index = (sorted.length - 1) * p;
const lower = Math.floor(index);
const upper = Math.ceil(index);
return Math.round((sorted[lower] * (1 - (index - lower)) + sorted[upper] * (index - lower)) * 100) / 100;
}
function arg(name) {
const index = process.argv.indexOf(name);
return index >= 0 ? process.argv[index + 1] : undefined;
}
+102
View File
@@ -0,0 +1,102 @@
#!/usr/bin/env node
import { execFileSync } from 'node:child_process';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const liveScript = path.join(root, 'skill/scripts/live.mjs');
const serverScript = path.join(root, 'skill/scripts/live-server.mjs');
const iterations = Math.max(1, Number(arg('--iterations') || 10));
const fixture = arg('--fixture') || 'vite8-react-plain';
const fixtureDir = path.join(root, 'tests/framework-fixtures', fixture, 'files');
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'impeccable-live-init-'));
try {
fs.cpSync(fixtureDir, tmp, { recursive: true });
fs.writeFileSync(path.join(tmp, 'PRODUCT.md'), '# Product\n\nA realistic Live initialization benchmark fixture.\n');
fs.writeFileSync(path.join(tmp, 'DESIGN.md'), '# Design\n\nUse the fixture\'s existing type, color, and component system.\n');
fs.mkdirSync(path.join(tmp, '.impeccable/live'), { recursive: true });
fs.writeFileSync(path.join(tmp, '.impeccable/live/config.json'), JSON.stringify({
files: ['index.html'],
insertBefore: '</body>',
commentSyntax: 'html',
cspChecked: true,
}, null, 2) + '\n');
const cold = [];
for (let i = 0; i < iterations; i += 1) {
stop();
cold.push(runLive());
}
stop();
runLive();
const warm = [];
for (let i = 0; i < iterations; i += 1) warm.push(runLive());
console.log(JSON.stringify({
fixture,
iterations,
measuredAt: new Date().toISOString(),
cold: summarize(cold),
warm: summarize(warm),
samples: { cold, warm },
}, null, 2));
} finally {
stop();
fs.rmSync(tmp, { recursive: true, force: true });
}
function runLive() {
const start = performance.now();
const stdout = execFileSync(process.execPath, [liveScript], {
cwd: tmp,
encoding: 'utf-8',
timeout: 15_000,
});
const elapsed = performance.now() - start;
const result = JSON.parse(stdout);
if (!result.ok) throw new Error('live init failed: ' + stdout);
return round(elapsed);
}
function stop() {
try {
execFileSync(process.execPath, [serverScript, 'stop'], {
cwd: tmp,
stdio: 'ignore',
timeout: 5_000,
});
} catch {}
}
function summarize(samples) {
const sorted = [...samples].sort((a, b) => a - b);
return {
medianMs: percentile(sorted, 0.5),
p95Ms: percentile(sorted, 0.95),
minMs: sorted[0],
maxMs: sorted.at(-1),
};
}
function percentile(sorted, value) {
if (sorted.length === 1) return sorted[0];
const index = (sorted.length - 1) * value;
const lower = Math.floor(index);
const upper = Math.ceil(index);
const weight = index - lower;
return round(sorted[lower] * (1 - weight) + sorted[upper] * weight);
}
function round(value) {
return Math.round(value * 100) / 100;
}
function arg(name) {
const index = process.argv.indexOf(name);
return index >= 0 ? process.argv[index + 1] : undefined;
}
+539
View File
@@ -0,0 +1,539 @@
#!/usr/bin/env node
import { execFile } from 'node:child_process';
import { readFile, writeFile, mkdir } from 'node:fs/promises';
import { dirname, join, resolve } from 'node:path';
import { performance } from 'node:perf_hooks';
import { promisify } from 'node:util';
import { fileURLToPath } from 'node:url';
import { bootFixtureSession, FIXTURES_DIR } from '../tests/live-e2e/session.mjs';
import { createFakeAgent } from '../tests/live-e2e/agent.mjs';
import {
clickAccept,
clickGo,
pickElement,
waitForCycling,
waitForHandshake,
} from '../tests/live-e2e/ui.mjs';
import {
BRAND_CONTRACT,
PROVIDER_PROFILES,
STRATEGIES,
applyRuntimeSourceScore,
createProviderLiveAgent,
loadBenchmarkEnv,
resolveProviderSelection,
scoreVariantOutput,
summarizeProviderRuns,
validateAcceptedCleanup,
} from './lib/live-provider-benchmark.mjs';
const execFileP = promisify(execFile);
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
const FIXTURE_NAME = 'vite8-react-brand-fidelity';
const SOURCE_FILE = 'src/App.jsx';
const args = parseArgs(process.argv.slice(2));
const iterations = positiveInt(args.iterations, 1);
const providers = csv(args.providers || 'anthropic,openai,google');
const strategies = csv(args.strategies || Object.keys(STRATEGIES).join(','));
const outputPath = args.output ? resolve(ROOT, String(args.output)) : null;
const loadedEnv = loadBenchmarkEnv({ repoRoot: ROOT, explicitPath: args.envFile ? resolve(String(args.envFile)) : null });
const modelOverrides = Object.fromEntries(providers.map((provider) => [provider, args[`${provider}Model`]]).filter(([, value]) => value));
const selection = resolveProviderSelection(providers, modelOverrides);
const fixture = JSON.parse(await readFile(join(FIXTURES_DIR, FIXTURE_NAME, 'fixture.json'), 'utf-8'));
const liveSpec = await readFile(join(ROOT, 'skill', 'reference', 'live.md'), 'utf-8');
validateConfiguration({ fixture, strategies, selection, liveSpec });
if (args.dryRun) {
const report = {
schemaVersion: 1,
generatedAt: new Date().toISOString(),
mode: 'dry-run',
fixture: FIXTURE_NAME,
iterations,
envFilesLoaded: loadedEnv.length,
providers: selection.map(publicProviderSelection),
strategies: strategies.map((strategy) => ({ strategy, ...STRATEGIES[strategy] })),
plannedApiCallsPerIteration: Object.fromEntries(strategies.map((strategy) => [strategy, callsPerStrategy(strategy)])),
qualityGate: qualityGateDescription(),
};
if (outputPath) await persist(report, outputPath);
process.stdout.write(JSON.stringify(report, null, 2) + '\n');
process.exit(0);
}
const available = selection.filter((item) => item.keyPresent);
if (args.requireAll && available.length !== selection.length) {
const missing = selection.filter((item) => !item.keyPresent).map((item) => item.provider);
throw new Error(`missing API keys for: ${missing.join(', ')}`);
}
if (available.length === 0) throw new Error('no provider API keys found; use --dry-run to validate without network calls');
const needsBrowser = args.pipeline === 'e2e' || args.skipCleanupControl !== true;
const { chromium } = needsBrowser ? await import('playwright') : { chromium: null };
const browser = chromium ? await chromium.launch({ headless: args.headed !== true }) : null;
const results = [];
let cleanupControl = { passed: true, skipped: true };
try {
if (args.skipCleanupControl !== true) {
process.stderr.write('[live-provider-bench] running provider-independent Accept/cleanup control\n');
cleanupControl = await runCleanupControl({ browser, fixture });
}
if (args.cleanupOnly) {
const cleanupReport = {
schemaVersion: 1,
generatedAt: new Date().toISOString(),
mode: 'cleanup-control',
fixture: FIXTURE_NAME,
cleanupControl,
};
if (outputPath) await persist(cleanupReport, outputPath);
process.stdout.write(JSON.stringify(cleanupReport, null, 2) + '\n');
process.exitCode = cleanupControl.passed ? 0 : 1;
}
if (args.cleanupOnly) {
// Skip provider calls; the finally block still closes Chromium.
} else {
for (const providerConfig of available) {
for (const strategy of strategies) {
for (let iteration = 1; iteration <= iterations; iteration += 1) {
process.stderr.write(`[live-provider-bench] ${providerConfig.provider}/${providerConfig.model} ${strategy} run ${iteration}/${iterations}\n`);
results.push(args.pipeline === 'e2e'
? await runOne({ browser, fixture, liveSpec, providerConfig, strategy, iteration })
: await runGenerationOne({ liveSpec, providerConfig, strategy, iteration, cleanupControl }));
}
}
}
}
} finally {
if (browser) await browser.close().catch(() => {});
}
if (args.cleanupOnly) process.exit(process.exitCode || 0);
const groups = [];
for (const providerConfig of selection) {
for (const strategy of strategies) {
const runs = results.filter((run) => run.provider === providerConfig.provider && run.strategy === strategy);
if (runs.length === 0) continue;
groups.push({
provider: providerConfig.provider,
model: providerConfig.model,
strategy,
strategyConfig: STRATEGIES[strategy],
summary: summarizeProviderRuns(runs),
runs,
});
}
}
const report = {
schemaVersion: 1,
generatedAt: new Date().toISOString(),
mode: 'live',
fixture: FIXTURE_NAME,
iterations,
providers: selection.map(publicProviderSelection),
qualityGate: qualityGateDescription(),
cleanupControl,
groups,
evaluations: evaluateStrategies(groups),
totals: {
apiCalls: results.reduce((sum, run) => sum + run.providerCalls.filter((call) => call.phase !== 'parallel-assembled').length, 0),
estimatedCostUsd: roundUsd(results.reduce((sum, run) => sum + run.estimatedCostUsd, 0)),
passingRuns: results.filter((run) => run.passed).length,
totalRuns: results.length,
},
};
if (outputPath) await persist(report, outputPath);
process.stdout.write(JSON.stringify(report, null, 2) + '\n');
async function runGenerationOne({ liveSpec: loadedLiveSpec, providerConfig, strategy, iteration, cleanupControl: cleanup }) {
const records = [];
const agent = createProviderLiveAgent({
provider: providerConfig.provider,
model: providerConfig.model,
strategy,
liveSpec: loadedLiveSpec,
onRecord: (record) => {
records.push(record);
const result = record.error ? `error=${record.error.split('\n')[0]}` : `duration=${record.durationMs ?? 0}ms`;
process.stderr.write(`[live-provider-bench:model] ${record.phase}${record.lane ? `/${record.lane}` : ''} attempt=${record.attempt} ${result}\n`);
},
});
const event = syntheticEvent(`${providerConfig.provider}-${strategy}-${iteration}`);
const startedAt = performance.now();
try {
let output;
let firstOutput;
let firstReviewableMs;
if (typeof agent.generateFirstVariant === 'function') {
firstOutput = await agent.generateFirstVariant(event, {});
firstReviewableMs = roundMs(performance.now() - startedAt);
output = await agent.generateRemainingVariants(event, { firstOutput });
} else {
output = await agent.generateVariants(event, {});
firstReviewableMs = roundMs(performance.now() - startedAt);
}
const allReadyMs = roundMs(performance.now() - startedAt);
const quality = scoreVariantOutput(output);
const estimatedCostUsd = roundUsd(records.reduce((sum, record) => sum + Number(record.estimatedCostUsd || 0), 0));
return {
provider: providerConfig.provider,
model: providerConfig.model,
strategy,
iteration,
firstReviewableMs,
allReadyMs,
acceptCleanupMs: cleanup.acceptCleanupMs ?? null,
quality,
cleanup,
firstOutputScore: firstOutput ? scoreVariantOutput(firstOutput) : quality,
providerCalls: records.map(publicProviderRecord),
estimatedCostUsd,
passed: quality.passed && cleanup.passed,
};
} catch (error) {
return {
provider: providerConfig.provider,
model: providerConfig.model,
strategy,
iteration,
error: String(error?.stack || error),
cleanup,
providerCalls: records.map(publicProviderRecord),
estimatedCostUsd: roundUsd(records.reduce((sum, record) => sum + Number(record.estimatedCostUsd || 0), 0)),
passed: false,
};
}
}
async function runCleanupControl({ browser, fixture: loadedFixture }) {
let session;
try {
session = await bootFixtureSession({
name: FIXTURE_NAME,
fixture: loadedFixture,
browser,
agent: createFakeAgent(),
wrapTarget: { classes: 'offer-card', tag: 'article', text: 'Field Notes' },
progressive: false,
log: args.verbose ? (message) => process.stderr.write(`[live-provider-bench:cleanup] ${message}\n`) : () => {},
});
await waitForHandshake(session.page);
await pickElement(session.page, loadedFixture.runtime.pickSelector);
await clickGo(session.page);
await waitForCycling(session.page, 3, { timeout: 45_000 });
const acceptAt = performance.now();
await clickAccept(session.page, { expectedVariant: 1 });
const browserClean = await waitForAcceptCleanup(session.page, session.tmp);
const acceptCleanupMs = roundMs(performance.now() - acceptAt);
const source = await readFile(join(session.tmp, SOURCE_FILE), 'utf-8');
const build = args.skipBuild ? { passed: true, skipped: true } : await verifyBuild(session.tmp);
return {
...validateAcceptedCleanup({ source, browserClean, buildPassed: build.passed }),
acceptCleanupMs,
build,
consoleErrorCount: session.consoleErrors.length,
};
} catch (error) {
return { passed: false, error: String(error?.stack || error) };
} finally {
if (session) await session.teardown();
}
}
async function runOne({ browser, fixture, liveSpec, providerConfig, strategy, iteration }) {
const records = [];
const agent = createProviderLiveAgent({
provider: providerConfig.provider,
model: providerConfig.model,
strategy,
liveSpec,
onRecord: (record) => {
records.push(record);
const result = record.error ? `error=${record.error.split('\n')[0]}` : `duration=${record.durationMs ?? 0}ms`;
process.stderr.write(`[live-provider-bench:model] ${record.phase}${record.lane ? `/${record.lane}` : ''} attempt=${record.attempt} ${result}\n`);
},
});
let session;
const startedAt = performance.now();
try {
session = await bootFixtureSession({
name: FIXTURE_NAME,
fixture,
browser,
agent,
wrapTarget: (event) => ({
classes: event.element?.classes?.join(',') || 'offer-card',
tag: event.element?.tagName?.toLowerCase() || 'article',
text: event.element?.textContent?.trim(),
}),
progressive: STRATEGIES[strategy].delivery !== 'atomic',
log: args.verbose ? (message) => process.stderr.write(`[live-provider-bench:e2e] ${message}\n`) : () => {},
});
await waitForHandshake(session.page);
await pickElement(session.page, fixture.runtime.pickSelector);
const goAt = performance.now();
const firstReady = waitForFirstReviewable(session.page);
await clickGo(session.page);
await firstReady;
const firstReviewableMs = roundMs(performance.now() - goAt);
await waitForCycling(session.page, 3, { timeout: 240_000 });
const allReadyMs = roundMs(performance.now() - goAt);
const finalRecord = [...records].reverse().find((record) => ['atomic', 'remaining', 'parallel-assembled'].includes(record.phase) && record.output);
if (!finalRecord) throw new Error('provider benchmark produced no complete variant output');
let quality = scoreVariantOutput(finalRecord.output);
const acceptAt = performance.now();
await clickAccept(session.page, { expectedVariant: 1 });
const browserClean = await waitForAcceptCleanup(session.page, session.tmp);
const acceptCleanupMs = roundMs(performance.now() - acceptAt);
const source = await readFile(join(session.tmp, SOURCE_FILE), 'utf-8');
const build = args.skipBuild ? { passed: true, skipped: true } : await verifyBuild(session.tmp);
const cleanup = validateAcceptedCleanup({ source, browserClean, buildPassed: build.passed });
quality = applyRuntimeSourceScore(quality, cleanup);
const estimatedCostUsd = roundUsd(records.reduce((sum, record) => sum + Number(record.estimatedCostUsd || 0), 0));
const passed = quality.passed && cleanup.passed;
return {
provider: providerConfig.provider,
model: providerConfig.model,
strategy,
iteration,
firstReviewableMs,
allReadyMs,
acceptCleanupMs,
endToEndMs: roundMs(performance.now() - startedAt),
quality,
cleanup,
build,
consoleErrorCount: session.consoleErrors.length,
providerCalls: records.map(publicProviderRecord),
estimatedCostUsd,
passed,
};
} catch (error) {
return {
provider: providerConfig.provider,
model: providerConfig.model,
strategy,
iteration,
error: String(error?.stack || error),
providerCalls: records.map(publicProviderRecord),
estimatedCostUsd: roundUsd(records.reduce((sum, record) => sum + Number(record.estimatedCostUsd || 0), 0)),
passed: false,
};
} finally {
if (session) await session.teardown();
}
}
async function waitForFirstReviewable(page) {
await page.waitForFunction(() => {
const query = window.__impeccableLiveQuery || ((selector) => document.querySelector(selector));
const wrapper = query('[data-impeccable-variants]');
if (!wrapper) return false;
const sourceVariants = wrapper.querySelectorAll('[data-impeccable-variant]:not([data-impeccable-variant="original"])');
const debug = window.__IMPECCABLE_LIVE_CHROME_CORE__?.debugState?.();
const arrived = wrapper.dataset.impeccablePreview === 'svelte-component'
? Number(debug?.arrivedVariants || 0)
: sourceVariants.length;
return arrived >= 1;
}, undefined, { timeout: 240_000 });
}
async function waitForAcceptCleanup(page, tmp) {
const deadline = Date.now() + 45_000;
while (Date.now() < deadline) {
const browserClean = await page.evaluate(() => {
const query = window.__impeccableLiveQuery || ((selector) => document.querySelector(selector));
const wrapperGone = !query('[data-impeccable-variants]');
const state = document.documentElement.dataset.impeccableLiveState;
return wrapperGone && (!state || state === 'PICKING');
}).catch(() => false);
const source = await readFile(join(tmp, SOURCE_FILE), 'utf-8').catch(() => '');
const sourceClean = source && !/data-impeccable-|impeccable-(?:variants|carbonize|params|original)/i.test(source);
if (browserClean && sourceClean) return true;
await new Promise((resolvePromise) => setTimeout(resolvePromise, 40));
}
return false;
}
async function verifyBuild(tmp) {
const startedAt = performance.now();
try {
await execFileP('npm', ['run', 'build'], { cwd: tmp, timeout: 120_000, maxBuffer: 4 * 1024 * 1024 });
return { passed: true, durationMs: roundMs(performance.now() - startedAt) };
} catch (error) {
return {
passed: false,
durationMs: roundMs(performance.now() - startedAt),
error: String(error?.stderr || error?.message || error).slice(0, 2000),
};
}
}
function evaluateStrategies(groups) {
const evaluations = [];
for (const provider of new Set(groups.map((group) => group.provider))) {
const providerGroups = groups.filter((group) => group.provider === provider);
const baseline = providerGroups.find((group) => group.strategy === 'atomic-full');
const baselineValid = baseline?.summary.gatePassRate === 1
&& Number.isFinite(baseline?.summary.metrics.firstReviewableMs?.median);
for (const group of providerGroups) {
const summary = group.summary;
const qualityPass = summary.gatePassRate === 1 && summary.cleanupPassRate === 1;
const first = summary.metrics.firstReviewableMs?.median;
const baselineFirst = baseline?.summary.metrics.firstReviewableMs?.median;
const firstImprovement = Number.isFinite(first) && Number.isFinite(baselineFirst) && baselineFirst > 0
? Number((1 - first / baselineFirst).toFixed(4))
: null;
const latencyPass = group.strategy === 'atomic-full'
|| (baselineValid ? firstImprovement != null && firstImprovement > 0.1 : Number.isFinite(first) && first < 15_000);
evaluations.push({
provider,
model: group.model,
strategy: group.strategy,
decision: qualityPass && latencyPass ? 'accept' : 'reject',
firstReviewableImprovementVsAtomic: firstImprovement,
qualityPass,
latencyPass,
reason: !qualityPass
? 'Rejected: fidelity, source validity, or cleanup gate failed.'
: !latencyPass
? 'Rejected: first-reviewable median did not improve by more than 10%.'
: group.strategy === 'atomic-full'
? 'Control: retained as the one-call baseline.'
: !baselineValid
? 'Accepted: quality passed and first review completed under 15 seconds; the atomic control was invalid for this provider.'
: 'Accepted: materially faster first review with all quality and cleanup gates intact.',
});
}
}
return evaluations;
}
function publicProviderSelection(item) {
return {
provider: item.provider,
label: item.label,
model: item.model,
keyPresent: item.keyPresent,
pricePerMillion: item.pricePerMillion,
effort: item.effort,
priceSource: item.priceSource,
};
}
function publicProviderRecord(record) {
return {
phase: record.phase,
lane: record.lane,
attempt: record.attempt,
durationMs: record.durationMs,
totalPhaseMs: record.totalPhaseMs,
usage: record.usage,
estimatedCostUsd: record.estimatedCostUsd,
error: record.error,
outputScore: record.output ? scoreVariantOutput(record.output) : undefined,
};
}
function qualityGateDescription() {
return {
deterministic: true,
pass: 'overall >= 0.90 and every dimension >= 0.75; accepted source must build and contain no Live markers',
dimensions: ['brandFidelity', 'componentFidelity', 'tokenFidelity', 'copyFidelity', 'sourceValidity', 'acceptCleanup'],
identityLock: BRAND_CONTRACT.identity,
};
}
function syntheticEvent(id) {
const outerHTML = BRAND_CONTRACT.sourceExcerpt
.replaceAll('className=', 'class=')
.replace(/\s+/g, ' ')
.trim();
return {
id,
action: 'impeccable',
freeformPrompt: 'Make this offer easier to scan while staying unmistakably inside the existing brand and component system.',
count: 3,
mode: 'replace',
element: {
outerHTML,
tagName: 'ARTICLE',
className: 'offer-card',
classes: ['offer-card'],
textContent: BRAND_CONTRACT.requiredCopy.join(' '),
},
};
}
function callsPerStrategy(strategy) {
if (strategy === 'atomic-full') return 1;
if (strategy === 'parallel-compact') return 3;
return 2;
}
function validateConfiguration({ fixture: loadedFixture, strategies: selectedStrategies, selection: selectedProviders, liveSpec: loadedLiveSpec }) {
if (!loadedFixture.runtime?.pickSelector) throw new Error('benchmark fixture requires runtime.pickSelector');
if (!loadedLiveSpec.includes('Phase A: Extract the identity')) throw new Error('live.md identity-lock guidance not found');
for (const strategy of selectedStrategies) if (!STRATEGIES[strategy]) throw new Error(`unknown strategy ${strategy}`);
if (selectedProviders.length === 0) throw new Error('at least one provider is required');
for (const provider of selectedProviders) if (!PROVIDER_PROFILES[provider.provider]) throw new Error(`unknown provider ${provider.provider}`);
}
async function persist(report, file) {
await mkdir(dirname(file), { recursive: true });
await writeFile(file, JSON.stringify(report, null, 2) + '\n', 'utf-8');
process.stderr.write(`[live-provider-bench] wrote ${file}\n`);
}
function parseArgs(argv) {
const out = {};
for (let position = 0; position < argv.length; position += 1) {
const arg = argv[position];
if (!arg.startsWith('--')) continue;
const body = arg.slice(2);
const index = body.indexOf('=');
if (index !== -1) {
out[camel(body.slice(0, index))] = body.slice(index + 1);
continue;
}
const next = argv[position + 1];
if (next !== undefined && !next.startsWith('--')) {
out[camel(body)] = next;
position += 1;
} else {
out[camel(body)] = true;
}
}
return out;
}
function camel(value) {
return value.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
}
function csv(value) {
return String(value).split(',').map((item) => item.trim()).filter(Boolean);
}
function positiveInt(value, fallback) {
const parsed = Number.parseInt(value, 10);
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
}
function roundMs(value) {
return Number(Number(value).toFixed(2));
}
function roundUsd(value) {
return Number(Number(value).toFixed(6));
}
+299
View File
@@ -0,0 +1,299 @@
#!/usr/bin/env node
import { mkdir, readFile, writeFile } from 'node:fs/promises';
import { dirname, join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { createFakeAgent } from '../tests/live-e2e/agent.mjs';
import { createLlmAgent, resolveLlmAgentConfig } from '../tests/live-e2e/agents/llm-agent.mjs';
import { bootFixtureSession, FIXTURES_DIR } from '../tests/live-e2e/session.mjs';
import {
clickDiscard,
clickGo,
drawAnnotationPinAndStroke,
pickElement,
waitForCycling,
waitForHandshake,
} from '../tests/live-e2e/ui.mjs';
import {
buildInteractionRun,
assembleSplitProgressiveOutput,
createBenchmarkReport,
createTraceRecorder,
mergeBenchmarkReports,
} from './lib/live-benchmark.mjs';
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
const args = parseArgs(process.argv.slice(2));
const fixtureName = String(args.fixture || 'vite8-react-plain');
const iterations = positiveInt(args.iterations, 5);
const agentMode = args.agent === 'llm' ? 'llm' : 'fake';
const scenario = args.scenario === 'annotated' ? 'annotated' : 'plain';
const delivery = args.delivery === 'progressive' ? 'progressive' : 'atomic';
const simulatedTailMs = positiveInt(args.simulatedTailMs, 0);
const outputPath = args.output ? resolve(ROOT, String(args.output)) : null;
const fixture = JSON.parse(await readFile(join(FIXTURES_DIR, fixtureName, 'fixture.json'), 'utf-8'));
if (!fixture.runtime) throw new Error(`fixture ${fixtureName} has no runtime configuration`);
if (fixture.runtime.mode === 'insert') throw new Error('live benchmark currently measures replace-mode fixtures only');
const { chromium } = await import('playwright');
const browser = await chromium.launch({ headless: args.headed !== true });
const recorder = createTraceRecorder();
let session;
try {
const agentInfo = await resolveAgent(agentMode, args);
if (delivery === 'progressive' && agentMode === 'llm') {
agentInfo.agent = createSplitProgressiveAgent(agentInfo.agent);
}
session = await bootFixtureSession({
name: fixtureName,
fixture,
browser,
agent: agentInfo.agent,
wrapTarget: wrapTargetFromPickedElement,
trace: recorder.trace,
progressive: delivery === 'progressive',
progressiveDelayMs: delivery === 'progressive' ? simulatedTailMs : 0,
atomicDelayMs: delivery === 'atomic' ? simulatedTailMs : 0,
log: args.quiet ? () => {} : (message) => process.stderr.write(`[live-bench] ${message}\n`),
});
recorder.mark('setup.handshake.start');
session.page.on('request', (request) => {
if (!request.url().endsWith('/events') || request.method() !== 'POST') return;
let payload;
try { payload = request.postDataJSON(); } catch { return; }
if (payload?.type === 'generate' && payload.id) {
recorder.mark('browser.generate_post', {
id: payload.id,
hasScreenshotPath: typeof payload.screenshotPath === 'string' && payload.screenshotPath.length > 0,
commentCount: Array.isArray(payload.comments) ? payload.comments.length : 0,
strokeCount: Array.isArray(payload.strokes) ? payload.strokes.length : 0,
});
}
});
await waitForHandshake(session.page);
recorder.mark('setup.handshake.end');
await installBrowserTimingProbe(session.page);
const runs = [];
const pickSelector = fixture.runtime.pickSelector || 'h1.hero-title';
for (let iteration = 1; iteration <= iterations; iteration += 1) {
await pickElement(session.page, pickSelector, { resetPickMode: iteration > 1 });
if (scenario === 'annotated') {
await drawAnnotationPinAndStroke(session.page, { comment: 'Benchmark annotation' });
}
await resetBrowserTimingProbe(session.page, iteration);
const goStarted = recorder.mark('ui.go.start', { iteration, scenario });
const firstVariant = waitForFirstVariant(session.page).then(() => {
recorder.mark('browser.first_variant', { iteration, scenario });
});
await clickGo(session.page);
recorder.mark('ui.generating_visible', { iteration, scenario });
await firstVariant;
await waitForCycling(session.page, 3, { timeout: agentMode === 'llm' ? 150_000 : 30_000 });
recorder.mark('browser.all_variants', { iteration, scenario });
const browserTiming = await readBrowserTimingProbe(session.page);
const run = buildInteractionRun(recorder.events, {
iteration,
scenario,
goStartedAt: goStarted.at,
browserTiming,
});
assertScenarioEvidence(run, scenario);
runs.push(run);
if (!args.quiet) process.stderr.write(formatRun(runs.at(-1)) + '\n');
await clickDiscard(session.page);
await waitForReset(session.page);
}
const report = createBenchmarkReport({
fixture: fixtureName,
agent: agentMode,
provider: agentInfo.provider,
model: agentInfo.model,
scenario,
runs,
events: recorder.events,
harnessProbe: args.harnessProbe || null,
delivery,
promptMode: agentInfo.promptMode,
simulation: simulatedTailMs > 0 ? { remainingGenerationMs: simulatedTailMs } : null,
});
let output = report;
if (outputPath && args.append) {
try {
const existing = JSON.parse(await readFile(outputPath, 'utf-8'));
const previousReports = Array.isArray(existing.reports) ? existing.reports : [existing];
output = mergeBenchmarkReports([...previousReports, report]);
} catch (error) {
if (error.code !== 'ENOENT') throw error;
}
}
const json = JSON.stringify(output, null, 2) + '\n';
if (outputPath) {
await mkdir(dirname(outputPath), { recursive: true });
await writeFile(outputPath, json, 'utf-8');
process.stderr.write(`[live-bench] wrote ${outputPath}\n`);
}
process.stdout.write(json);
} finally {
if (session) await session.teardown();
await browser.close().catch(() => {});
}
async function resolveAgent(mode, options) {
if (mode === 'fake') return { agent: createFakeAgent(), provider: 'deterministic', model: null, promptMode: null };
const config = resolveLlmAgentConfig({
provider: options.provider,
model: options.model,
});
const agent = await createLlmAgent({
config,
includeLiveSpec: false,
log: (message) => process.stderr.write(`[live-bench:llm] ${message}\n`),
});
if (!agent) {
throw new Error(`LLM benchmark provider=${config.provider} requires ${config.requiredEnv}. Pass it in the environment; .env files are not read implicitly.`);
}
return { agent, provider: config.provider, model: config.model, promptMode: 'synthetic-element-contract' };
}
function createSplitProgressiveAgent(agent) {
const firstBySession = new Map();
return {
...agent,
async generateFirstVariant(event, context) {
const first = await agent.generateVariants({
...event,
count: 1,
progressive: { phase: 'first', totalCount: event.count },
}, context);
firstBySession.set(event.id, first);
return first;
},
async generateRemainingVariants(event, context) {
const first = firstBySession.get(event.id) || context.firstOutput;
const remaining = await agent.generateVariants({
...event,
count: event.count,
progressive: {
phase: 'remaining',
totalCount: event.count,
firstVariant: first?.variants?.[0] || null,
omitFirstVariantCss: true,
},
}, context);
firstBySession.delete(event.id);
return assembleSplitProgressiveOutput(first, remaining);
},
};
}
async function waitForFirstVariant(page) {
const handle = await page.waitForFunction(() => {
const wrappers = [...document.querySelectorAll('[data-impeccable-variant]')];
return wrappers.some((element) => element.getAttribute('data-impeccable-variant') !== 'original');
}, undefined, { timeout: 150_000 });
await handle.dispose();
}
async function waitForReset(page) {
await page.waitForFunction(() => !document.querySelector('[data-impeccable-variants]'), undefined, { timeout: 30_000 });
await page.waitForTimeout(100);
}
async function installBrowserTimingProbe(page) {
await page.evaluate(() => {
const state = { iteration: 0, goAt: null, generateAt: null };
window.__IMPECCABLE_LIVE_BENCH_TIMING__ = state;
const root = window.__IMPECCABLE_LIVE_CHROME_CORE__?.root?.()
|| window.__IMPECCABLE_LIVE_UI_ROOT__
|| document;
root.addEventListener('click', (event) => {
const button = event.composedPath().find((node) =>
node?.getAttribute?.('aria-label') === 'Generate variants'
);
if (button) state.goAt = performance.now();
}, true);
const originalFetch = window.fetch.bind(window);
window.fetch = (input, init) => {
try {
const url = typeof input === 'string' ? input : input?.url;
if (String(url || '').endsWith('/events') && init?.method === 'POST') {
const payload = typeof init.body === 'string' ? JSON.parse(init.body) : null;
if (payload?.type === 'generate') state.generateAt = performance.now();
}
} catch { /* measurement must never affect Live */ }
return originalFetch(input, init);
};
});
}
async function resetBrowserTimingProbe(page, iteration) {
await page.evaluate((nextIteration) => {
const state = window.__IMPECCABLE_LIVE_BENCH_TIMING__;
if (!state) return;
state.iteration = nextIteration;
state.goAt = null;
state.generateAt = null;
}, iteration);
}
async function readBrowserTimingProbe(page) {
return page.evaluate(() => {
const state = window.__IMPECCABLE_LIVE_BENCH_TIMING__;
return state ? { ...state } : null;
});
}
function assertScenarioEvidence(run, currentScenario) {
const evidence = run.annotationEvidence;
if (currentScenario === 'annotated') {
if (!evidence?.screenshotPath || evidence.comments < 1 || evidence.strokes < 1) {
throw new Error(`iteration ${run.iteration}: annotated generate payload lost screenshot/comments/strokes`);
}
return;
}
if (evidence?.screenshotPath) {
throw new Error(`iteration ${run.iteration}: plain generate payload unexpectedly included screenshotPath`);
}
}
function wrapTargetFromPickedElement(event) {
const element = event.element || {};
return {
elementId: element.id || undefined,
classes: Array.isArray(element.classes) ? element.classes.join(',') : undefined,
tag: element.tagName ? String(element.tagName).toLowerCase() : undefined,
text: element.textContent ? String(element.textContent).trim() : undefined,
};
}
function parseArgs(argv) {
const out = {};
for (const arg of argv) {
if (!arg.startsWith('--')) continue;
const body = arg.slice(2);
const index = body.indexOf('=');
if (index === -1) out[body] = true;
else out[body.slice(0, index)] = body.slice(index + 1);
}
return out;
}
function positiveInt(value, fallback) {
const parsed = Number.parseInt(value, 10);
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
}
function formatRun(run) {
return `[live-bench] run ${run.iteration}: first=${run.goToFirstVariantMs}ms all=${run.goToAllVariantsMs}ms generation=${run.generationMs}ms overhead=${run.impeccableOverheadMs}ms`;
}
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env node
import { readFile } from 'node:fs/promises';
import { resolve } from 'node:path';
import { compareModelBackedReports } from './lib/live-benchmark.mjs';
const args = parseArgs(process.argv.slice(2));
if (!args.atomic || !args.progressive) {
throw new Error('usage: node scripts/compare-live-benchmarks.mjs --atomic=<report.json> --progressive=<report.json>');
}
const [atomic, progressive] = await Promise.all([
readReport(args.atomic, 'atomic'),
readReport(args.progressive, 'progressive'),
]);
const comparison = compareModelBackedReports(atomic, progressive, {
medianTarget: ratioArg(args.medianTarget, 0.35),
p95Target: ratioArg(args.p95Target, 0.25),
});
process.stdout.write(JSON.stringify(comparison, null, 2) + '\n');
if (!comparison.passed) process.exitCode = 1;
async function readReport(file, delivery) {
const value = JSON.parse(await readFile(resolve(String(file)), 'utf-8'));
const reports = Array.isArray(value?.reports) ? value.reports : [value];
const report = reports.find((item) => item?.benchmark?.delivery === delivery);
if (!report) throw new Error(`${file} does not contain a ${delivery} benchmark report`);
return report;
}
function parseArgs(argv) {
const out = {};
for (const arg of argv) {
if (!arg.startsWith('--')) continue;
const index = arg.indexOf('=');
if (index > 2) out[arg.slice(2, index)] = arg.slice(index + 1);
}
return out;
}
function ratioArg(value, fallback) {
if (value == null) return fallback;
const parsed = Number(value);
if (!Number.isFinite(parsed) || parsed < 0 || parsed >= 1) throw new Error(`invalid threshold ratio: ${value}`);
return parsed;
}
+395
View File
@@ -0,0 +1,395 @@
import { performance } from 'node:perf_hooks';
const METRIC_KEYS = [
'browserPreparationMs',
'browserDispatchMs',
'automationClickMs',
'serverPickupMs',
'goToAgentMs',
'serverPreflightMs',
'scaffoldMs',
'generationToFirstMs',
'generationMs',
'firstVariantWriteMs',
'writeMs',
'writeToFirstVariantMs',
'replyMs',
'goToFirstVariantMs',
'goToAllVariantsMs',
'deliveryGapMs',
'impeccableOverheadMs',
];
export function createTraceRecorder(now = () => performance.now()) {
const events = [];
return {
events,
trace(name, data = {}) {
events.push({ name, at: now(), ...data });
},
mark(name, data = {}) {
const event = { name, at: now(), ...data };
events.push(event);
return event;
},
};
}
export function durationBetween(events, startName, endName, predicate = () => true) {
const start = events.find((event) => event.name === startName && predicate(event));
const end = events.find((event) => event.name === endName && predicate(event) && (!start || event.at >= start.at));
if (!start || !end) return null;
return roundMs(Math.max(0, end.at - start.at));
}
/**
* Assemble the two model calls used by the Live benchmark's progressive path.
* The first checkpoint is already visible in the browser, so both its markup
* and CSS are immutable. The tail call may supply deferred params for variant
* 1, but its CSS must contain only independently-scoped rules for variants 2+.
*/
export function assembleSplitProgressiveOutput(first, remaining) {
const firstVariant = first?.variants?.[0];
if (!firstVariant) throw new Error('progressive assembly requires a first variant');
if (!Array.isArray(remaining?.variants) || remaining.variants.length < 1) {
throw new Error('progressive assembly requires a complete remaining variant set');
}
const firstCss = String(first.scopedCss || '');
const laterCss = String(remaining.scopedCss || '');
assertLaterVariantCss(laterCss);
return {
scopedCss: firstCss && laterCss ? `${firstCss}\n${laterCss}` : firstCss || laterCss,
variants: [
{
...firstVariant,
params: Array.isArray(remaining.variants[0]?.params)
? remaining.variants[0].params
: [],
},
...remaining.variants.slice(1),
],
};
}
export function buildInteractionRun(events, { iteration, scenario, goStartedAt, browserTiming = null }) {
const received = events.find((event) =>
event.name === 'agent.event.received'
&& event.type === 'generate'
&& event.at >= goStartedAt
);
if (!received?.id) throw new Error(`iteration ${iteration}: no generate event was traced`);
const id = received.id;
const forId = (event) => event.id === id;
const eventPost = events.find((event) => event.name === 'browser.generate_post' && forId(event));
const mark = (name) => events.find((event) => event.name === name && event.iteration === iteration);
const first = mark('browser.first_variant');
const all = mark('browser.all_variants');
const writeEnd = events.find((event) => event.name === 'agent.write.end' && forId(event));
const firstWriteEnd = events.find((event) => event.name === 'agent.first_variant.write.end' && forId(event));
const reusedScaffold = events.find((event) => event.name === 'agent.scaffold.reused' && forId(event));
const generationMs = durationBetween(events, 'agent.generate.start', 'agent.generate.end', forId);
const generationToFirstMs = durationBetween(events, 'agent.generate.start', 'agent.generate.first_ready', forId);
const browserPreparationMs = eventPost ? roundMs(eventPost.at - goStartedAt) : null;
const browserDispatchMs = Number.isFinite(browserTiming?.goAt) && Number.isFinite(browserTiming?.generateAt)
? roundMs(Math.max(0, browserTiming.generateAt - browserTiming.goAt))
: null;
const interactionStartedAt = eventPost && browserDispatchMs != null
? eventPost.at - browserDispatchMs
: goStartedAt;
const measuredGoToFirstVariantMs = first ? roundMs(first.at - interactionStartedAt) : null;
const measuredGoToAllVariantsMs = all ? roundMs(all.at - interactionStartedAt) : null;
return {
iteration,
scenario,
eventId: id,
annotationEvidence: {
screenshotPath: eventPost?.hasScreenshotPath === true,
comments: Number(eventPost?.commentCount || 0),
strokes: Number(eventPost?.strokeCount || 0),
},
browserPreparationMs,
browserDispatchMs,
automationClickMs: browserPreparationMs == null || browserDispatchMs == null
? null
: roundMs(Math.max(0, browserPreparationMs - browserDispatchMs)),
serverPickupMs: eventPost ? roundMs(Math.max(0, received.at - eventPost.at)) : null,
goToAgentMs: roundMs(received.at - interactionStartedAt),
serverPreflightMs: Number.isFinite(reusedScaffold?.durationMs) ? roundMs(reusedScaffold.durationMs) : null,
scaffoldMs: durationBetween(events, 'agent.scaffold.start', 'agent.scaffold.end', forId),
generationToFirstMs,
generationMs,
firstVariantWriteMs: durationBetween(events, 'agent.first_variant.write.start', 'agent.first_variant.write.end', forId),
writeMs: durationBetween(events, 'agent.write.start', 'agent.write.end', forId),
writeToFirstVariantMs: first && (firstWriteEnd || writeEnd)
? roundMs(Math.max(0, first.at - (firstWriteEnd || writeEnd).at))
: null,
replyMs: durationBetween(events, 'agent.reply.start', 'agent.reply.end', forId),
goToFirstVariantMs: measuredGoToFirstVariantMs,
goToAllVariantsMs: measuredGoToAllVariantsMs,
deliveryGapMs: first && all ? roundMs(Math.max(0, all.at - first.at)) : null,
impeccableOverheadMs: measuredGoToFirstVariantMs == null || generationToFirstMs == null
? null
: roundMs(Math.max(0, measuredGoToFirstVariantMs - generationToFirstMs)),
};
}
export function summarizeRuns(runs) {
const metrics = {};
for (const key of METRIC_KEYS) {
const values = runs.map((run) => run[key]).filter(Number.isFinite).sort((a, b) => a - b);
if (values.length === 0) continue;
metrics[key] = {
median: roundMs(percentile(values, 0.5)),
p95: roundMs(percentile(values, 0.95)),
min: roundMs(values[0]),
max: roundMs(values[values.length - 1]),
};
}
return { count: runs.length, metrics };
}
export function summarizeSetup(events) {
const stages = [
['dependencies', 'setup.install.start', 'setup.install.end'],
['liveServer', 'setup.live_server.start', 'setup.live_server.end'],
['injection', 'setup.inject.start', 'setup.inject.end'],
['devServer', 'setup.dev_server.start', 'setup.dev_server.end'],
['pageLoad', 'setup.page_load.start', 'setup.page_load.end'],
['handshake', 'setup.handshake.start', 'setup.handshake.end'],
];
return Object.fromEntries(stages.map(([key, start, end]) => [key, durationBetween(events, start, end)]));
}
export function createBenchmarkReport({
fixture,
agent,
provider,
model,
scenario,
runs,
events,
harnessProbe = null,
delivery = 'atomic',
promptMode = null,
simulation = null,
generatedAt = new Date().toISOString(),
}) {
return {
schemaVersion: 1,
generatedAt,
benchmark: {
fixture,
agent,
provider: provider || null,
model: model || null,
scenario,
variants: 3,
delivery,
promptMode,
simulation,
},
setup: summarizeSetup(events),
summary: summarizeRuns(runs),
runs,
harnessProbe,
};
}
export function mergeBenchmarkReports(reports, generatedAt = new Date().toISOString()) {
return {
schemaVersion: 1,
generatedAt,
reports,
};
}
export function compareModelBackedReports(atomic, progressive, {
medianTarget = 0.35,
p95Target = 0.25,
minimumRuns = 3,
} = {}) {
assertComparableModelReport(atomic, 'atomic', minimumRuns);
assertComparableModelReport(progressive, 'progressive', minimumRuns);
for (const key of ['fixture', 'provider', 'model', 'scenario', 'variants', 'promptMode']) {
if (atomic.benchmark[key] !== progressive.benchmark[key]) {
throw new Error(`benchmark mismatch for ${key}: atomic=${atomic.benchmark[key]} progressive=${progressive.benchmark[key]}`);
}
}
const atomicFirst = requiredMetric(atomic, 'goToFirstVariantMs');
const progressiveFirst = requiredMetric(progressive, 'goToFirstVariantMs');
const medianImprovement = improvement(atomicFirst.median, progressiveFirst.median);
const p95Improvement = improvement(atomicFirst.p95, progressiveFirst.p95);
const allReady = {
atomic: requiredMetric(atomic, 'goToAllVariantsMs'),
progressive: requiredMetric(progressive, 'goToAllVariantsMs'),
};
const passed = medianImprovement >= medianTarget && p95Improvement >= p95Target;
return {
passed,
target: { medianImprovement, p95Improvement, medianTarget, p95Target },
firstReviewable: { atomic: atomicFirst, progressive: progressiveFirst },
allVariantsReady: allReady,
benchmark: {
fixture: atomic.benchmark.fixture,
provider: atomic.benchmark.provider,
model: atomic.benchmark.model,
scenario: atomic.benchmark.scenario,
runs: { atomic: atomic.summary.count, progressive: progressive.summary.count },
},
};
}
function assertComparableModelReport(report, delivery, minimumRuns) {
if (!report?.benchmark || !report?.summary) throw new Error(`${delivery} benchmark report is missing metadata or summary`);
if (report.benchmark.agent !== 'llm') throw new Error(`${delivery} benchmark must be model-backed (agent=llm)`);
if (report.benchmark.delivery !== delivery) {
throw new Error(`expected ${delivery} delivery report, got ${report.benchmark.delivery || 'unknown'}`);
}
if (report.benchmark.simulation) throw new Error(`${delivery} model benchmark must not contain simulated latency`);
if (!report.benchmark.provider || !report.benchmark.model) throw new Error(`${delivery} benchmark is missing provider/model identity`);
if (!Number.isInteger(report.summary.count) || report.summary.count < minimumRuns) {
throw new Error(`${delivery} benchmark requires at least ${minimumRuns} runs`);
}
}
function requiredMetric(report, key) {
const metric = report.summary.metrics?.[key];
if (!Number.isFinite(metric?.median) || !Number.isFinite(metric?.p95)) {
throw new Error(`${report.benchmark.delivery} benchmark is missing ${key} median/p95`);
}
return { median: metric.median, p95: metric.p95 };
}
function improvement(baseline, candidate) {
if (!(baseline > 0) || !Number.isFinite(candidate)) throw new Error('benchmark latency must be finite and baseline must be positive');
return Number((1 - (candidate / baseline)).toFixed(4));
}
function assertLaterVariantCss(css) {
if (!css.trim()) return;
for (const prelude of topLevelCssPreludes(css)) {
const variants = [...prelude.matchAll(/\[data-impeccable-variant\s*=\s*(["'])(\d+)\1[^\]]*\]/g)]
.map((match) => Number(match[2]));
if (variants.includes(1)) {
throw new Error('progressive tail CSS must not repeat or conflict with published variant 1 CSS');
}
if (variants.length === 0 || variants.some((variant) => variant < 2)) {
throw new Error('progressive tail CSS must be attributable only to variants 2+');
}
if (new Set(variants).size !== 1) {
throw new Error('each progressive tail CSS block must target exactly one later variant');
}
}
}
function topLevelCssPreludes(css) {
const preludes = [];
let cursor = 0;
while (cursor < css.length) {
while (cursor < css.length && /\s/.test(css[cursor])) cursor += 1;
if (cursor >= css.length) break;
const start = cursor;
const open = findCssToken(css, cursor, '{');
if (open === -1) throw new Error('progressive tail CSS contains a rule without a block');
const prelude = css.slice(start, open).trim();
if (!prelude || prelude.includes(';')) {
throw new Error('progressive tail CSS must contain scoped rule blocks only');
}
preludes.push(prelude);
const close = findMatchingCssBrace(css, open);
if (close === -1) throw new Error('progressive tail CSS has unbalanced braces');
cursor = close + 1;
}
return preludes;
}
function findCssToken(css, start, token) {
let quote = null;
let comment = false;
for (let index = start; index < css.length; index += 1) {
const char = css[index];
const next = css[index + 1];
if (comment) {
if (char === '*' && next === '/') {
comment = false;
index += 1;
}
continue;
}
if (!quote && char === '/' && next === '*') {
comment = true;
index += 1;
continue;
}
if (quote) {
if (char === '\\') index += 1;
else if (char === quote) quote = null;
continue;
}
if (char === '"' || char === "'") {
quote = char;
continue;
}
if (char === token) return index;
}
return -1;
}
function findMatchingCssBrace(css, open) {
let depth = 0;
let quote = null;
let comment = false;
for (let index = open; index < css.length; index += 1) {
const char = css[index];
const next = css[index + 1];
if (comment) {
if (char === '*' && next === '/') {
comment = false;
index += 1;
}
continue;
}
if (!quote && char === '/' && next === '*') {
comment = true;
index += 1;
continue;
}
if (quote) {
if (char === '\\') index += 1;
else if (char === quote) quote = null;
continue;
}
if (char === '"' || char === "'") {
quote = char;
continue;
}
if (char === '{') depth += 1;
if (char === '}') {
depth -= 1;
if (depth === 0) return index;
}
}
return -1;
}
function percentile(sortedValues, ratio) {
if (sortedValues.length === 1) return sortedValues[0];
const index = (sortedValues.length - 1) * ratio;
const lower = Math.floor(index);
const upper = Math.ceil(index);
if (lower === upper) return sortedValues[lower];
const weight = index - lower;
return sortedValues[lower] * (1 - weight) + sortedValues[upper] * weight;
}
function roundMs(value) {
if (!Number.isFinite(value)) return null;
return Number(value.toFixed(2));
}
+547
View File
@@ -0,0 +1,547 @@
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { performance } from 'node:perf_hooks';
import { anthropic } from '@ai-sdk/anthropic';
import { google } from '@ai-sdk/google';
import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
import {
VARIANT_SYSTEM_INSTRUCTIONS,
parseVariantResponse,
validateProgressiveVariantOutput,
validateVariantCount,
validateVariantMaterialChange,
validateVariantVisibleCopy,
} from '../../tests/live-e2e/agents/llm-agent.mjs';
export const PROVIDER_PROFILES = Object.freeze({
anthropic: {
label: 'Anthropic',
model: 'claude-sonnet-4-6',
envKeys: ['ANTHROPIC_API_KEY'],
pricePerMillion: { input: 3, cachedInput: 0.3, output: 15 },
effort: 'low',
priceSource: 'https://platform.claude.com/docs/en/about-claude/pricing',
},
openai: {
label: 'OpenAI',
model: 'gpt-5.5',
envKeys: ['OPENAI_API_KEY'],
pricePerMillion: { input: 5, cachedInput: 0.5, output: 30 },
effort: 'low',
priceSource: 'https://developers.openai.com/api/docs/models/gpt-5.5',
},
google: {
label: 'Google',
model: 'gemini-3.1-flash-lite',
envKeys: ['GOOGLE_GENERATIVE_AI_API_KEY', 'GOOGLE_CLOUD_API_KEY', 'GEMINI_API_KEY'],
pricePerMillion: { input: 0.25, cachedInput: 0.025, output: 1.5 },
effort: 'minimal (provider default)',
priceSource: 'https://ai.google.dev/gemini-api/docs/pricing',
},
});
export const STRATEGIES = Object.freeze({
'atomic-full': {
delivery: 'atomic',
promptMode: 'full-live-context',
calls: 'one 3-variant call',
},
'progressive-full': {
delivery: 'progressive',
promptMode: 'full-live-context',
calls: 'one first-variant call, then one remaining-directions call; deterministic assembly preserves variant 1',
},
'progressive-compact': {
delivery: 'progressive',
promptMode: 'compact-producer-contract',
calls: 'one first-variant call, then one remaining-directions call; deterministic assembly preserves variant 1',
},
'parallel-compact': {
delivery: 'parallel-progressive',
promptMode: 'compact-producer-contract',
calls: 'three concurrent one-variant calls; first valid result publishes immediately',
},
});
export const BRAND_CONTRACT = Object.freeze({
identity: 'Warm paper, dark ink, moss and brass accents; Georgia display with a restrained sans body; editorial, practical, and quiet.',
requiredCopy: [
'Quarterly print edition',
'Field Notes',
'Four routes, annotated maps, and practical details for unhurried weekends.',
'Reserve issue eight',
],
requiredClasses: [
'offer-card',
'offer-card__copy',
'offer-card__eyebrow',
'offer-card__title',
'offer-card__body',
'action-link',
],
allowedTokens: [
'--color-paper',
'--color-paper-deep',
'--color-ink',
'--color-moss',
'--color-brass',
'--font-display',
'--font-body',
'--space-1',
'--space-2',
'--space-3',
'--space-4',
'--radius-control',
],
sourceExcerpt: [
'<article className="offer-card" aria-labelledby="field-notes-title">',
' <div className="offer-card__copy">',
' <p className="offer-card__eyebrow">Quarterly print edition</p>',
' <h2 className="offer-card__title" id="field-notes-title">Field Notes</h2>',
' <p className="offer-card__body">Four routes, annotated maps, and practical details for unhurried weekends.</p>',
' </div>',
' <a className="action-link" href="#edition">Reserve issue eight</a>',
'</article>',
].join('\n'),
});
const COMPACT_CONTRACT = [
VARIANT_SYSTEM_INSTRUCTIONS,
'',
'QUALITY GATE FOR THIS PRODUCER:',
'- Preserve all visible copy exactly and retain the article/component class contract.',
'- Stay inside the supplied identity. Reuse the supplied CSS custom properties instead of inventing colors, typefaces, spacing, or radii.',
'- Do not add gradients, blur, glow, glass, neon, decorative shadows, emoji, or unrelated content.',
'- Make each variant materially different through hierarchy, layout, density, or color-role allocation.',
].join('\n');
export function loadBenchmarkEnv({ repoRoot, explicitPath } = {}) {
const candidates = [
explicitPath,
repoRoot && path.join(repoRoot, '.env'),
path.join(os.homedir(), 'code', 'impeccable-evals', '.env'),
].filter(Boolean);
const loaded = [];
for (const file of candidates) {
if (!fs.existsSync(file)) continue;
const body = fs.readFileSync(file, 'utf-8');
for (const line of body.split(/\r?\n/)) {
const match = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/);
if (!match || match[1].startsWith('#')) continue;
let value = match[2];
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
value = value.slice(1, -1);
}
if (!process.env[match[1]] && value) process.env[match[1]] = value;
}
loaded.push(file);
}
if (!process.env.GOOGLE_GENERATIVE_AI_API_KEY) {
process.env.GOOGLE_GENERATIVE_AI_API_KEY = process.env.GOOGLE_CLOUD_API_KEY || process.env.GEMINI_API_KEY;
}
return loaded;
}
export function resolveProviderSelection(providerNames, modelOverrides = {}) {
return providerNames.map((provider) => {
const profile = PROVIDER_PROFILES[provider];
if (!profile) throw new Error(`unknown provider ${JSON.stringify(provider)}`);
const keyPresent = profile.envKeys.some((key) => Boolean(process.env[key]));
return {
provider,
label: profile.label,
model: modelOverrides[provider] || profile.model,
keyPresent,
pricePerMillion: profile.pricePerMillion,
effort: profile.effort,
priceSource: profile.priceSource,
};
});
}
export function createProviderLiveAgent({ provider, model, strategy, liveSpec, onRecord = () => {} }) {
const strategyConfig = STRATEGIES[strategy];
if (!strategyConfig) throw new Error(`unknown strategy ${JSON.stringify(strategy)}`);
const languageModel = providerModel(provider, model);
const system = strategyConfig.promptMode === 'full-live-context'
? `${COMPACT_CONTRACT}\n\nFULL LIVE CONTEXT:\n${liveSpec}`
: COMPACT_CONTRACT;
const pendingParallel = new Map();
const pendingFirst = new Map();
const request = async ({ event, phase, lane = null, firstVariant = null }) => {
const startedAt = performance.now();
const expectedCount = Number(event.count);
const payload = benchmarkPayload(event, { phase, lane, firstVariant });
const basePrompt = [
'Produce Impeccable Live variant output for this request. Return only the JSON object.',
phaseInstructions(phase, expectedCount, lane),
'',
'<benchmark_context>',
JSON.stringify(payload, null, 2),
'</benchmark_context>',
].join('\n');
let prompt = basePrompt;
let lastError;
for (let attempt = 1; attempt <= 2; attempt += 1) {
const attemptStartedAt = performance.now();
let usage = null;
try {
const response = await generateText({
model: languageModel,
system,
prompt,
maxOutputTokens: 12_000,
...providerLatencyOptions(provider),
});
usage = normalizeUsage(response.usage);
const parsed = parseVariantResponse(response.text);
const validationError = validateVariantOutput(parsed, event, { phase, firstVariant });
if (validationError) throw new Error(validationError);
const record = {
provider,
model,
strategy,
phase,
lane,
attempt,
durationMs: roundMs(performance.now() - attemptStartedAt),
totalPhaseMs: roundMs(performance.now() - startedAt),
usage,
estimatedCostUsd: estimateCostUsd(usage, PROVIDER_PROFILES[provider].pricePerMillion),
output: parsed,
};
onRecord(record);
return parsed;
} catch (error) {
lastError = error;
onRecord({
provider,
model,
strategy,
phase,
lane,
attempt,
durationMs: roundMs(performance.now() - attemptStartedAt),
usage,
estimatedCostUsd: usage ? estimateCostUsd(usage, PROVIDER_PROFILES[provider].pricePerMillion) : 0,
error: String(error?.message || error),
});
prompt = `${basePrompt}\n\nVALIDATION ERROR:\n${String(error?.message || error)}\nReturn corrected JSON only.`;
}
}
throw lastError;
};
if (strategy === 'atomic-full') {
return {
async generateVariants(event) {
return request({ event, phase: 'atomic' });
},
};
}
if (strategy === 'parallel-compact') {
return {
async generateFirstVariant(event) {
const lanes = ['hierarchy', 'layout', 'density'];
const calls = lanes.map((lane) => {
const laneEvent = { ...event, count: 1 };
return request({ event: laneEvent, phase: 'parallel-lane', lane }).then((output) => ({ lane, output }));
});
const first = await Promise.race(calls);
pendingParallel.set(event.id, { calls, first });
return first.output;
},
async generateRemainingVariants(event) {
const pending = pendingParallel.get(event.id);
if (!pending) throw new Error(`parallel generation state missing for ${event.id}`);
const settled = await Promise.all(pending.calls);
pendingParallel.delete(event.id);
const ordered = [pending.first, ...settled.filter((item) => item !== pending.first)];
const variants = ordered.map((item) => item.output.variants[0]);
const scopedCss = ordered.map((item, index) => remapSingleVariantCss(item.output.scopedCss, index + 1)).join('\n');
const output = { scopedCss, variants };
onRecord({ provider, model, strategy, phase: 'parallel-assembled', lane: null, attempt: 1, usage: normalizeUsage(), estimatedCostUsd: 0, output });
return output;
},
};
}
return {
async generateFirstVariant(event) {
const first = await request({ event: { ...event, count: 1 }, phase: 'first' });
pendingFirst.set(event.id, first);
return first;
},
async generateRemainingVariants(event, context) {
const first = pendingFirst.get(event.id) || context.firstOutput;
if (!first?.variants?.[0]) throw new Error(`first variant state missing for ${event.id}`);
const remaining = await request({
event: { ...event, count: Math.max(1, event.count - 1) },
phase: 'remaining-directions',
firstVariant: first.variants[0],
});
pendingFirst.delete(event.id);
return assembleProgressiveOutput(first, remaining);
},
};
}
export function scoreVariantOutput(output, { validationError = null } = {}) {
const variants = Array.isArray(output?.variants) ? output.variants : [];
const css = String(output?.scopedCss || '');
const perVariant = variants.map((variant) => String(variant.innerHtml || ''));
const copyChecks = perVariant.flatMap((html) => BRAND_CONTRACT.requiredCopy.map((copy) => html.includes(copy)));
const componentChecks = perVariant.flatMap((html) => [
/^\s*<article\b/i.test(html),
/\bclass=["'][^"']*\boffer-card\b/.test(html),
...BRAND_CONTRACT.requiredClasses.slice(1).map((className) => new RegExp(`\\b${escapeRegExp(className)}\\b`).test(html)),
/href=["']#edition["']/.test(html),
/aria-labelledby=["']field-notes-title["']/.test(html),
]);
const usedTokens = BRAND_CONTRACT.allowedTokens.filter((token) => css.includes(`var(${token}`));
const rawColors = css.match(/#[0-9a-f]{3,8}\b|\b(?:rgb|hsl|oklch|lab)\s*\(/gi) || [];
const foreignFonts = css.match(/font-family\s*:\s*([^;}]+)/gi) || [];
const tokenChecks = [
usedTokens.length >= 3,
rawColors.length === 0,
foreignFonts.every((declaration) => /var\(--font-(?:display|body)\)|inherit|serif|sans-serif/.test(declaration)),
!/\b(?:margin|padding|gap|border-radius)\s*:\s*(?!var\(|0(?:\D|$))[^;}]+/i.test(css),
];
const brandChecks = [
/var\(--color-(?:paper|paper-deep|ink|moss|brass)\)/.test(css),
!/(?:linear|radial|conic)-gradient|backdrop-filter|filter\s*:\s*blur|text-shadow|box-shadow/i.test(css),
!/\b(?:neon|glass|glow|purple|magenta|cyan)\b/i.test(`${css}\n${perVariant.join('\n')}`),
!/border-radius\s*:\s*(?:999|[5-9]\d)px/i.test(css),
];
const sourceChecks = [
!validationError,
variants.length > 0,
perVariant.every((html) => !/data-impeccable-|<script|<style/i.test(html)),
perVariant.every((html) => /^\s*<article\b[\s\S]*<\/article>\s*$/i.test(html)),
];
const dimensions = {
brandFidelity: dimension(brandChecks),
componentFidelity: dimension(componentChecks),
tokenFidelity: dimension(tokenChecks),
copyFidelity: dimension(copyChecks),
sourceValidity: dimension(sourceChecks),
};
const overall = roundScore(Object.values(dimensions).reduce((sum, value) => sum + value, 0) / Object.keys(dimensions).length);
return {
...dimensions,
overall,
passed: overall >= 0.9 && Object.values(dimensions).every((value) => value >= 0.75),
diagnostics: {
usedTokens,
rawColorCount: rawColors.length,
validationError,
},
};
}
export function validateAcceptedCleanup({ source, browserClean, buildPassed, expectedCopy = BRAND_CONTRACT.requiredCopy }) {
const markerFree = !/data-impeccable-|impeccable-(?:variants|carbonize|params|original)/i.test(source);
const copyPreserved = expectedCopy.every((copy) => source.includes(copy));
const sourceShape = /<article\b[^>]*\boffer-card\b[\s\S]*<\/article>/.test(source);
const checks = { markerFree, copyPreserved, sourceShape, browserClean: Boolean(browserClean), buildPassed: Boolean(buildPassed) };
return { ...checks, passed: Object.values(checks).every(Boolean) };
}
export function applyRuntimeSourceScore(quality, cleanup) {
const sourceChecks = [cleanup.markerFree, cleanup.copyPreserved, cleanup.sourceShape, cleanup.browserClean, cleanup.buildPassed];
const sourceValidity = dimension(sourceChecks);
const dimensions = {
brandFidelity: quality.brandFidelity,
componentFidelity: quality.componentFidelity,
tokenFidelity: quality.tokenFidelity,
copyFidelity: quality.copyFidelity,
sourceValidity,
};
const overall = roundScore(Object.values(dimensions).reduce((sum, value) => sum + value, 0) / Object.keys(dimensions).length);
return {
...quality,
...dimensions,
overall,
passed: cleanup.passed === true && overall >= 0.9 && Object.values(dimensions).every((value) => value >= 0.75),
};
}
export function assembleProgressiveOutput(first, remaining) {
if (!first?.variants?.[0]) throw new Error('progressive assembly requires a first variant');
if (!Array.isArray(remaining?.variants) || remaining.variants.length === 0) {
throw new Error('progressive assembly requires remaining variants');
}
return {
scopedCss: [first.scopedCss, shiftVariantCss(remaining.scopedCss, 1)].filter(Boolean).join('\n'),
variants: [first.variants[0], ...remaining.variants],
};
}
export function summarizeProviderRuns(runs) {
const latencyKeys = ['firstReviewableMs', 'allReadyMs', 'acceptCleanupMs'];
const metrics = {};
for (const key of latencyKeys) {
const values = runs.map((run) => run[key]).filter(Number.isFinite).sort((a, b) => a - b);
if (values.length) metrics[key] = summarizeNumbers(values);
}
const qualityKeys = ['brandFidelity', 'componentFidelity', 'tokenFidelity', 'copyFidelity', 'sourceValidity', 'overall'];
const quality = {};
for (const key of qualityKeys) {
const values = runs.map((run) => run.quality?.[key]).filter(Number.isFinite).sort((a, b) => a - b);
if (values.length) quality[key] = summarizeNumbers(values);
}
return {
count: runs.length,
metrics,
quality,
cleanupPassRate: runs.length ? roundScore(runs.filter((run) => run.cleanup?.passed).length / runs.length) : 0,
gatePassRate: runs.length ? roundScore(runs.filter((run) => run.passed).length / runs.length) : 0,
estimatedCostUsd: roundUsd(runs.reduce((sum, run) => sum + Number(run.estimatedCostUsd || 0), 0)),
};
}
function providerModel(provider, model) {
if (provider === 'anthropic') return anthropic(model);
if (provider === 'openai') return openai(model);
if (provider === 'google') return google(model);
throw new Error(`unsupported provider ${provider}`);
}
function providerLatencyOptions(provider) {
if (provider === 'anthropic') return { providerOptions: { anthropic: { effort: 'low' } } };
if (provider === 'openai') return { providerOptions: { openai: { reasoningEffort: 'low' } } };
// Gemini 3.1 Flash-Lite defaults to minimal thinking; leaving the provider
// option unset preserves that latency-oriented default across SDK versions.
return {};
}
function benchmarkPayload(event, { phase, lane, firstVariant }) {
return {
request: {
id: event.id,
action: event.action,
freeformPrompt: event.freeformPrompt,
count: event.count,
phase,
lane,
firstVariant,
},
pickedElement: event.element,
identityLock: BRAND_CONTRACT.identity,
sourceExcerpt: BRAND_CONTRACT.sourceExcerpt,
availableTokens: BRAND_CONTRACT.allowedTokens,
componentContract: {
rootTag: 'article',
requiredClasses: BRAND_CONTRACT.requiredClasses,
requiredHref: '#edition',
requiredAriaLabelledby: 'field-notes-title',
exactVisibleCopy: BRAND_CONTRACT.requiredCopy,
},
};
}
function phaseInstructions(phase, count, lane) {
if (phase === 'first') {
return 'Return exactly one variant. Use params: [] so tunables stay off the first-reviewable path.';
}
if (phase === 'remaining-directions') {
return `Return exactly ${count} new variants for different axes. Do not reproduce request.firstVariant; assembly preserves that first output byte-for-byte.`;
}
if (phase === 'parallel-lane') {
return `Return exactly one complete variant whose primary difference axis is ${lane}. It must stand alone and may include 0-3 useful params.`;
}
return `Return exactly ${count} complete variants in one response.`;
}
function validateVariantOutput(parsed, event, { phase, firstVariant }) {
const phaseEvent = phase === 'first'
? { ...event, progressive: { phase: 'first', totalCount: 3 } }
: event;
return validateVariantCount(parsed, phaseEvent)
|| validateProgressiveVariantOutput(parsed, phaseEvent)
|| validateVariantVisibleCopy(parsed, event.element)
|| validateVariantMaterialChange(parsed, event.element);
}
function remapSingleVariantCss(css, variantNumber) {
return String(css)
.replaceAll('[data-impeccable-variant="1"]', `[data-impeccable-variant="${variantNumber}"]`)
.replaceAll("[data-impeccable-variant='1']", `[data-impeccable-variant='${variantNumber}']`);
}
function shiftVariantCss(css, amount) {
return String(css).replace(/(data-impeccable-variant=["'])(\d+)(["'])/g, (_, before, number, after) => {
return `${before}${Number(number) + amount}${after}`;
});
}
function normalizeUsage(usage = {}) {
const input = numberFrom(usage.inputTokens, usage.promptTokens, usage.inputTokenDetails?.noCacheTokens);
const cached = numberFrom(usage.cachedInputTokens, usage.inputTokenDetails?.cacheReadTokens, usage.inputTokenDetails?.cachedTokens);
const output = numberFrom(usage.outputTokens, usage.completionTokens);
return {
inputTokens: input,
cachedInputTokens: cached,
outputTokens: output,
totalTokens: numberFrom(usage.totalTokens, input + output),
};
}
export function estimateCostUsd(usage, pricing) {
const cached = Math.min(usage.cachedInputTokens || 0, usage.inputTokens || 0);
const uncached = Math.max(0, (usage.inputTokens || 0) - cached);
return roundUsd((
uncached * pricing.input
+ cached * pricing.cachedInput
+ (usage.outputTokens || 0) * pricing.output
) / 1_000_000);
}
function numberFrom(...values) {
for (const value of values) if (Number.isFinite(value)) return Number(value);
return 0;
}
function dimension(checks) {
return checks.length ? roundScore(checks.filter(Boolean).length / checks.length) : 0;
}
function summarizeNumbers(values) {
return {
median: roundMs(percentile(values, 0.5)),
p95: roundMs(percentile(values, 0.95)),
min: roundMs(values[0]),
max: roundMs(values.at(-1)),
};
}
function percentile(values, ratio) {
if (values.length === 1) return values[0];
const index = (values.length - 1) * ratio;
const lower = Math.floor(index);
const upper = Math.ceil(index);
if (lower === upper) return values[lower];
return values[lower] + (values[upper] - values[lower]) * (index - lower);
}
function escapeRegExp(value) {
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
function roundMs(value) {
return Number(Number(value).toFixed(2));
}
function roundScore(value) {
return Number(Number(value).toFixed(4));
}
function roundUsd(value) {
return Number(Number(value).toFixed(6));
}