chore: generate

This commit is contained in:
opencode-agent[bot]
2026-07-08 16:30:17 +00:00
parent ccd8676bee
commit a72c3880bb
6 changed files with 82 additions and 67 deletions
@@ -1205,7 +1205,9 @@ function modelComparisonPairs(
}, },
detail: "Usage peer", detail: "Usage peer",
})) }))
const catalogPairs = (catalogEntry && catalog ? catalog.labs.find((lab) => lab.id === catalogEntry.lab)?.models ?? [] : []) const catalogPairs = (
catalogEntry && catalog ? (catalog.labs.find((lab) => lab.id === catalogEntry.lab)?.models ?? []) : []
)
.filter((model) => model.id !== catalogEntry?.id) .filter((model) => model.id !== catalogEntry?.id)
.slice(0, 3) .slice(0, 3)
.map((model) => ({ .map((model) => ({
@@ -28,11 +28,7 @@ import {
import { SectionHeading } from "../section-heading" import { SectionHeading } from "../section-heading"
import { runStatsEffect } from "../../stats-runtime" import { runStatsEffect } from "../../stats-runtime"
import { setStatsPageCacheHeaders } from "../stats-cache" import { setStatsPageCacheHeaders } from "../stats-cache"
import { import { ComparisonCardsSection, modelRefFromCatalog, uniqueComparisonPairs } from "../compare-cards"
ComparisonCardsSection,
modelRefFromCatalog,
uniqueComparisonPairs,
} from "../compare-cards"
import { import {
applyThemePreference, applyThemePreference,
Footer, Footer,
@@ -1,9 +1,6 @@
import "../../../../index.css" import "../../../../index.css"
import { Link, Meta, Title } from "@solidjs/meta" import { Link, Meta, Title } from "@solidjs/meta"
import { import { getStatsModelComparisonData, type StatsModelComparisonEntry } from "@opencode-ai/stats-core/domain/home"
getStatsModelComparisonData,
type StatsModelComparisonEntry,
} from "@opencode-ai/stats-core/domain/home"
import { runtime } from "@opencode-ai/stats-core/runtime" import { runtime } from "@opencode-ai/stats-core/runtime"
import { createAsync, query, useParams } from "@solidjs/router" import { createAsync, query, useParams } from "@solidjs/router"
import { createMemo, createSignal, For, onMount, Show } from "solid-js" import { createMemo, createSignal, For, onMount, Show } from "solid-js"
@@ -124,7 +121,11 @@ export default function ModelComparePair() {
const rows = createMemo(() => buildComparisonRows(models()[0], models()[1])) const rows = createMemo(() => buildComparisonRows(models()[0], models()[1]))
const relatedPairs = createMemo(() => buildRelatedPairs(catalog(), models()[0], models()[1])) const relatedPairs = createMemo(() => buildRelatedPairs(catalog(), models()[0], models()[1]))
const selectorModels = createMemo(() => const selectorModels = createMemo(() =>
uniqueCatalogModels([comparisonCatalogEntry(models()[0]), comparisonCatalogEntry(models()[1]), ...(catalog()?.models ?? [])]), uniqueCatalogModels([
comparisonCatalogEntry(models()[0]),
comparisonCatalogEntry(models()[1]),
...(catalog()?.models ?? []),
]),
) )
const structuredData = createMemo(() => const structuredData = createMemo(() =>
JSON.stringify({ JSON.stringify({
@@ -176,17 +177,16 @@ export default function ModelComparePair() {
<ComparisonHero models={models()} /> <ComparisonHero models={models()} />
<section id="comparison" data-section="model-panel"> <section id="comparison" data-section="model-panel">
<p data-slot="section-title"> <p data-slot="section-title">
<strong>Comparison Table.</strong>{" "} <strong>Comparison Table.</strong> <span>Compare usage, cost, limits, and features.</span>
<span>Compare usage, cost, limits, and features.</span>
</p> </p>
<Show <Show
when={stats() !== undefined} when={stats() !== undefined}
fallback={ fallback={
<div data-component="empty-state" data-compact="true"> <div data-component="empty-state" data-compact="true">
<strong>Loading comparison</strong> <strong>Loading comparison</strong>
<p>Loading stats for both models.</p> <p>Loading stats for both models.</p>
</div> </div>
} }
> >
<ComparisonTable models={models()} rows={rows()} /> <ComparisonTable models={models()} rows={rows()} />
</Show> </Show>
@@ -197,12 +197,12 @@ export default function ModelComparePair() {
</p> </p>
<Show <Show
when={selectorModels().length > 1} when={selectorModels().length > 1}
fallback={ fallback={
<div data-component="empty-state" data-compact="true"> <div data-component="empty-state" data-compact="true">
<strong>No models found</strong> <strong>No models found</strong>
<p>The model list could not be loaded.</p> <p>The model list could not be loaded.</p>
</div> </div>
} }
> >
<ComparisonSelector <ComparisonSelector
models={selectorModels()} models={selectorModels()}
@@ -337,18 +337,18 @@ function uniqueCatalogModels(models: ModelCatalogEntry[]) {
function buildComparisonRows(first: ComparisonModel, second: ComparisonModel): ComparisonRow[] { function buildComparisonRows(first: ComparisonModel, second: ComparisonModel): ComparisonRow[] {
return [ return [
comparisonRow( comparisonRow(
"Recent Rank", "Recent Rank",
"Lower is better.", "Lower is better.",
{ {
value: first.stats?.rank == null ? "No usage" : `#${first.stats.rank}`, value: first.stats?.rank == null ? "No usage" : `#${first.stats.rank}`,
score: first.stats?.rank ?? undefined, score: first.stats?.rank ?? undefined,
}, },
{ {
value: second.stats?.rank == null ? "No usage" : `#${second.stats.rank}`, value: second.stats?.rank == null ? "No usage" : `#${second.stats.rank}`,
score: second.stats?.rank ?? undefined, score: second.stats?.rank ?? undefined,
}, },
"lower", "lower",
), ),
comparisonRow( comparisonRow(
"Token Share", "Token Share",
"Share of recent OpenCode usage.", "Share of recent OpenCode usage.",
@@ -408,7 +408,10 @@ function buildComparisonRows(first: ComparisonModel, second: ComparisonModel): C
comparisonRow( comparisonRow(
"Cache Ratio", "Cache Ratio",
"Higher is better.", "Higher is better.",
{ value: first.stats ? formatPercent(first.stats.totals.cacheRatio) : "No usage", score: first.stats?.totals.cacheRatio }, {
value: first.stats ? formatPercent(first.stats.totals.cacheRatio) : "No usage",
score: first.stats?.totals.cacheRatio,
},
{ {
value: second.stats ? formatPercent(second.stats.totals.cacheRatio) : "No usage", value: second.stats ? formatPercent(second.stats.totals.cacheRatio) : "No usage",
score: second.stats?.totals.cacheRatio, score: second.stats?.totals.cacheRatio,
+31 -25
View File
@@ -294,10 +294,7 @@ function CompareModelSelectModal(props: {
return availableModels().filter((model) => terms.every((term) => modelSearchText(model).includes(term))) return availableModels().filter((model) => terms.every((term) => modelSearchText(model).includes(term)))
}) })
const preview = createMemo( const preview = createMemo(
() => () => filteredModels().find((model) => model.id === previewId()) ?? filteredModels()[0] ?? availableModels()[0],
filteredModels().find((model) => model.id === previewId()) ??
filteredModels()[0] ??
availableModels()[0],
) )
createEffect(() => { createEffect(() => {
@@ -395,7 +392,10 @@ function CompareModelDetail(props: { model: ModelCatalogEntry }) {
<strong>{props.model.name}</strong> <strong>{props.model.name}</strong>
</header> </header>
<div data-slot="compare-model-modal-description"> <div data-slot="compare-model-modal-description">
<p>{props.model.description ?? `${props.model.name} is an AI model from ${formatCatalogLabName(props.model.lab)}.`}</p> <p>
{props.model.description ??
`${props.model.name} is an AI model from ${formatCatalogLabName(props.model.lab)}.`}
</p>
<span aria-hidden="true" /> <span aria-hidden="true" />
</div> </div>
<dl data-slot="compare-model-modal-facts"> <dl data-slot="compare-model-modal-facts">
@@ -464,7 +464,9 @@ function CompareHomeCard(props: { category: CompareCategory }) {
<span>{props.category.second.name}</span> <span>{props.category.second.name}</span>
</span> </span>
<span data-slot="compare-home-card-avatars" aria-hidden="true"> <span data-slot="compare-home-card-avatars" aria-hidden="true">
<For each={props.category.avatars}>{(model) => <LabLogo lab={model.lab} label={model.name} size="small" />}</For> <For each={props.category.avatars}>
{(model) => <LabLogo lab={model.lab} label={model.name} size="small" />}
</For>
</span> </span>
</a> </a>
) )
@@ -485,22 +487,25 @@ function LabLogo(props: { lab: string; label: string; size: "large" | "small" |
} }
function buildComparisonCategories(models: ModelCatalogEntry[]): CompareCategory[] { function buildComparisonCategories(models: ModelCatalogEntry[]): CompareCategory[] {
return categoryTemplates.reduce<{ keys: Set<string>; categories: CompareCategory[] }>((result, template, index) => { return categoryTemplates.reduce<{ keys: Set<string>; categories: CompareCategory[] }>(
const candidates = categoryCandidates(template.kind, models) (result, template, index) => {
const pair = categoryPair(candidates, models, index, result.keys) const candidates = categoryCandidates(template.kind, models)
if (!pair) return result const pair = categoryPair(candidates, models, index, result.keys)
result.keys.add(comparisonKey(pair.first, pair.second)) if (!pair) return result
const first = modelRefFromCatalog(pair.first) result.keys.add(comparisonKey(pair.first, pair.second))
const second = modelRefFromCatalog(pair.second) const first = modelRefFromCatalog(pair.first)
result.categories.push({ const second = modelRefFromCatalog(pair.second)
title: template.title, result.categories.push({
description: template.description, title: template.title,
first, description: template.description,
second, first,
avatars: [first, second], second,
}) avatars: [first, second],
return result })
}, { keys: new Set(), categories: [] }).categories return result
},
{ keys: new Set(), categories: [] },
).categories
} }
function categoryPair( function categoryPair(
@@ -525,9 +530,10 @@ function categoryCandidates(kind: (typeof categoryTemplates)[number]["kind"], mo
if (kind === "affordable") if (kind === "affordable")
return models return models
.filter((model) => model.cost) .filter((model) => model.cost)
.toSorted((a, b) => modelCost(a) - modelCost(b) || displayDateTime(b.releaseDate) - displayDateTime(a.releaseDate)) .toSorted(
if (kind === "code") (a, b) => modelCost(a) - modelCost(b) || displayDateTime(b.releaseDate) - displayDateTime(a.releaseDate),
return models.filter((model) => model.toolCall || model.reasoning).toSorted(recentModelSort) )
if (kind === "code") return models.filter((model) => model.toolCall || model.reasoning).toSorted(recentModelSort)
if (kind === "image") if (kind === "image")
return models return models
.filter((model) => model.modalities.output.some((modality) => modality.toLowerCase().includes("image"))) .filter((model) => model.modalities.output.some((modality) => modality.toLowerCase().includes("image")))
+9 -3
View File
@@ -5726,11 +5726,15 @@
} }
[data-page="stats"] [data-component="compare-home-selector"] button[data-slot="compare-home-select-panel"]:hover, [data-page="stats"] [data-component="compare-home-selector"] button[data-slot="compare-home-select-panel"]:hover,
[data-page="stats"] [data-component="compare-home-selector"] button[data-slot="compare-home-select-panel"]:focus-within { [data-page="stats"]
[data-component="compare-home-selector"]
button[data-slot="compare-home-select-panel"]:focus-within {
background: var(--stats-layer); background: var(--stats-layer);
} }
[data-page="stats"] [data-component="compare-home-selector"] button[data-slot="compare-home-select-panel"]:focus-visible { [data-page="stats"]
[data-component="compare-home-selector"]
button[data-slot="compare-home-select-panel"]:focus-visible {
z-index: 1; z-index: 1;
outline: 1px solid var(--stats-line-strong); outline: 1px solid var(--stats-line-strong);
outline-offset: -1px; outline-offset: -1px;
@@ -6043,7 +6047,9 @@
[data-page="stats"] [data-component="compare-model-modal"] button[data-slot="compare-model-modal-row"]:hover, [data-page="stats"] [data-component="compare-model-modal"] button[data-slot="compare-model-modal-row"]:hover,
[data-page="stats"] [data-component="compare-model-modal"] button[data-slot="compare-model-modal-row"]:focus-visible, [data-page="stats"] [data-component="compare-model-modal"] button[data-slot="compare-model-modal-row"]:focus-visible,
[data-page="stats"] [data-component="compare-model-modal"] button[data-slot="compare-model-modal-row"][data-active="true"] { [data-page="stats"]
[data-component="compare-model-modal"]
button[data-slot="compare-model-modal-row"][data-active="true"] {
color: var(--stats-text); color: var(--stats-text);
background: var(--stats-layer-2); background: var(--stats-layer-2);
outline: none; outline: none;
@@ -243,7 +243,9 @@ export function Footer(props: {
{ href: "https://www.youtube.com/@anomaly-co", label: i18n.t("footer.youtube") }, { href: "https://www.youtube.com/@anomaly-co", label: i18n.t("footer.youtube") },
] ]
const bridge = () => const bridge = () =>
props.bridge === undefined ? { href: "#geo-breakdown", label: i18n.t("nav.geoBreakdown").toUpperCase() } : props.bridge props.bridge === undefined
? { href: "#geo-breakdown", label: i18n.t("nav.geoBreakdown").toUpperCase() }
: props.bridge
return ( return (
<footer data-component="footer"> <footer data-component="footer">