Mike0021 commited on
Commit
837ca85
·
verified ·
1 Parent(s): 54f7d3e

Add benchmark JSON download

Browse files
Files changed (4) hide show
  1. README.md +2 -0
  2. app.js +26 -12
  3. index.html +1 -0
  4. styles.css +1 -0
README.md CHANGED
@@ -18,6 +18,8 @@ Static browser demo for client-side voice interaction:
18
 
19
  Open the Space, click **Load models**, then **Start mic**. The first load downloads model assets into the browser cache; after that, inference runs in the tab with no server inference.
20
 
 
 
21
  Known testing notes:
22
 
23
  - Use Chrome or another browser with WebGPU/WASM support and microphone permission enabled.
 
18
 
19
  Open the Space, click **Load models**, then **Start mic**. The first load downloads model assets into the browser cache; after that, inference runs in the tab with no server inference.
20
 
21
+ After benchmark or real-mic runs, use **Download JSON** to save the `{ summary, results }` evidence file locally.
22
+
23
  Known testing notes:
24
 
25
  - Use Chrome or another browser with WebGPU/WASM support and microphone permission enabled.
app.js CHANGED
@@ -13,6 +13,7 @@ const elements = {
13
  micBenchmarkButton: $("micBenchmarkButton"),
14
  micSeriesButton: $("micSeriesButton"),
15
  copyResultsButton: $("copyResultsButton"),
 
16
  clearResultsButton: $("clearResultsButton"),
17
  clearLogButton: $("clearLogButton"),
18
  deviceSelect: $("deviceSelect"),
@@ -1524,6 +1525,7 @@ function parseMetricMs(text) {
1524
  function renderBenchmarkResults() {
1525
  elements.resultsBody.replaceChildren();
1526
  elements.copyResultsButton.disabled = state.benchmarkResults.length === 0;
 
1527
  elements.clearResultsButton.disabled = state.benchmarkResults.length === 0;
1528
  renderBenchmarkSummary();
1529
  if (state.benchmarkResults.length === 0) {
@@ -1630,6 +1632,27 @@ function exportBenchmarkSummary() {
1630
  };
1631
  }
1632
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1633
  function benchmarkSummariesByStack() {
1634
  const grouped = new Map();
1635
  for (const result of state.benchmarkResults) {
@@ -2452,10 +2475,7 @@ function installAutomationApi() {
2452
  version: 1,
2453
  state: automationSnapshot,
2454
  exportResults() {
2455
- return {
2456
- summary: exportBenchmarkSummary(),
2457
- results: [...state.benchmarkResults],
2458
- };
2459
  },
2460
  webgpuInfo: automationWebGpuInfo,
2461
  setRuntimeOptions(options = {}) {
@@ -2534,14 +2554,7 @@ elements.bargeInButton.addEventListener("click", runBargeInBenchmark);
2534
  elements.micBenchmarkButton.addEventListener("click", runMicBenchmark);
2535
  elements.micSeriesButton.addEventListener("click", runMicSeriesBenchmark);
2536
  elements.copyResultsButton.addEventListener("click", () => {
2537
- const payload = JSON.stringify(
2538
- {
2539
- summary: exportBenchmarkSummary(),
2540
- results: state.benchmarkResults,
2541
- },
2542
- null,
2543
- 2,
2544
- );
2545
  const write = navigator.clipboard?.writeText(payload);
2546
  if (write) {
2547
  write.then(() => logEvent("Benchmark JSON copied.")).catch(() => logEvent(payload));
@@ -2549,6 +2562,7 @@ elements.copyResultsButton.addEventListener("click", () => {
2549
  logEvent(payload);
2550
  }
2551
  });
 
2552
  elements.clearResultsButton.addEventListener("click", () => {
2553
  cancelMicSeries();
2554
  clearBenchmarkTimeout();
 
13
  micBenchmarkButton: $("micBenchmarkButton"),
14
  micSeriesButton: $("micSeriesButton"),
15
  copyResultsButton: $("copyResultsButton"),
16
+ downloadResultsButton: $("downloadResultsButton"),
17
  clearResultsButton: $("clearResultsButton"),
18
  clearLogButton: $("clearLogButton"),
19
  deviceSelect: $("deviceSelect"),
 
1525
  function renderBenchmarkResults() {
1526
  elements.resultsBody.replaceChildren();
1527
  elements.copyResultsButton.disabled = state.benchmarkResults.length === 0;
1528
+ elements.downloadResultsButton.disabled = state.benchmarkResults.length === 0;
1529
  elements.clearResultsButton.disabled = state.benchmarkResults.length === 0;
1530
  renderBenchmarkSummary();
1531
  if (state.benchmarkResults.length === 0) {
 
1632
  };
1633
  }
1634
 
1635
+ function benchmarkExportPayload() {
1636
+ return {
1637
+ summary: exportBenchmarkSummary(),
1638
+ results: [...state.benchmarkResults],
1639
+ };
1640
+ }
1641
+
1642
+ function downloadBenchmarkJson() {
1643
+ const payload = JSON.stringify(benchmarkExportPayload(), null, 2);
1644
+ const blob = new Blob([`${payload}\n`], { type: "application/json" });
1645
+ const url = URL.createObjectURL(blob);
1646
+ const anchor = document.createElement("a");
1647
+ anchor.href = url;
1648
+ anchor.download = `browser-speak-benchmarks-${new Date().toISOString().replace(/[:.]/g, "-")}.json`;
1649
+ document.body.append(anchor);
1650
+ anchor.click();
1651
+ anchor.remove();
1652
+ window.setTimeout(() => URL.revokeObjectURL(url), 1000);
1653
+ logEvent("Benchmark JSON download started.");
1654
+ }
1655
+
1656
  function benchmarkSummariesByStack() {
1657
  const grouped = new Map();
1658
  for (const result of state.benchmarkResults) {
 
2475
  version: 1,
2476
  state: automationSnapshot,
2477
  exportResults() {
2478
+ return benchmarkExportPayload();
 
 
 
2479
  },
2480
  webgpuInfo: automationWebGpuInfo,
2481
  setRuntimeOptions(options = {}) {
 
2554
  elements.micBenchmarkButton.addEventListener("click", runMicBenchmark);
2555
  elements.micSeriesButton.addEventListener("click", runMicSeriesBenchmark);
2556
  elements.copyResultsButton.addEventListener("click", () => {
2557
+ const payload = JSON.stringify(benchmarkExportPayload(), null, 2);
 
 
 
 
 
 
 
2558
  const write = navigator.clipboard?.writeText(payload);
2559
  if (write) {
2560
  write.then(() => logEvent("Benchmark JSON copied.")).catch(() => logEvent(payload));
 
2562
  logEvent(payload);
2563
  }
2564
  });
2565
+ elements.downloadResultsButton.addEventListener("click", downloadBenchmarkJson);
2566
  elements.clearResultsButton.addEventListener("click", () => {
2567
  cancelMicSeries();
2568
  clearBenchmarkTimeout();
index.html CHANGED
@@ -200,6 +200,7 @@
200
  <h2>Benchmarks</h2>
201
  <div class="mini-actions">
202
  <button id="copyResultsButton" type="button" disabled>Copy JSON</button>
 
203
  <button id="clearResultsButton" type="button" disabled>Clear</button>
204
  </div>
205
  </div>
 
200
  <h2>Benchmarks</h2>
201
  <div class="mini-actions">
202
  <button id="copyResultsButton" type="button" disabled>Copy JSON</button>
203
+ <button id="downloadResultsButton" type="button" disabled>Download JSON</button>
204
  <button id="clearResultsButton" type="button" disabled>Clear</button>
205
  </div>
206
  </div>
styles.css CHANGED
@@ -451,6 +451,7 @@ h2 {
451
 
452
  .mini-actions {
453
  display: flex;
 
454
  gap: 8px;
455
  }
456
 
 
451
 
452
  .mini-actions {
453
  display: flex;
454
+ flex-wrap: wrap;
455
  gap: 8px;
456
  }
457