fix(stats): refine lab page tooltips

This commit is contained in:
Adam 2026-07-01 14:54:01 -05:00
parent 5668d36477
commit beb586a383
No known key found for this signature in database
GPG key ID: 9CB48779AF150E75
3 changed files with 39 additions and 8 deletions

View file

@ -469,6 +469,12 @@ function LabUsageSection(props: { lab: ModelCatalogLab; data: StatsLabData | nul
</span>
<b>{formatTokens(active.point.tokens)}</b>
</p>
<p>
<span data-slot="tooltip-label">
<i data-kind="users" /> {i18n.t("model.uniqueUsers")}
</span>
<b>{formatUsers(active.point.users)}</b>
</p>
</div>
)
}}
@ -759,7 +765,7 @@ function relatedLabStats(labs: ModelCatalogLab[], market: MarketDay[]) {
}
function labRelatedDescription(lab: ModelCatalogLab) {
return lab.description ?? `OpenCode Go usage across ${lab.name} models, recent token volume, and model limits.`
return lab.description ?? ""
}
function relatedTone(share: number) {

View file

@ -4218,7 +4218,7 @@
[data-page="stats"] [data-component="model-usage-chart"][data-variant="lab-usage"] [data-component="chart-tooltip"] {
z-index: 6;
top: clamp(12px, calc(var(--lab-usage-user-y) * 1% - 38px), calc(100% - 92px));
top: clamp(12px, calc(var(--lab-usage-user-y) * 1% - 46px), calc(100% - 108px));
width: 192px;
min-width: 192px;
background: var(--stats-bg);
@ -4240,7 +4240,7 @@
[data-page="stats"] [data-component="model-usage-chart"][data-variant="lab-usage"] [data-component="chart-tooltip"] p {
height: 16px;
margin: 8px 0;
margin: 4px 0;
}
[data-page="stats"]
@ -4250,6 +4250,13 @@
background: var(--lab-usage-active);
}
[data-page="stats"]
[data-component="model-usage-chart"][data-variant="lab-usage"]
[data-component="chart-tooltip"]
i[data-kind="users"] {
background: var(--lab-usage-line);
}
[data-page="stats"] [data-component="model-peer-list"] {
display: grid;
gap: 8px;

View file

@ -2,6 +2,7 @@ import { query } from "@solidjs/router"
export const modelCatalogSourceUrl = "https://models.dev/catalog.json"
export const modelCatalogPricingUrl = "https://models.dev/api.json"
export const modelCatalogLabSourceUrl = "https://models.dev/labs"
export type ModelCatalogCost = {
input: number
@ -57,11 +58,12 @@ export type ModelCatalog = {
export const getModelCatalog = query(async () => {
"use server"
const [models, pricing] = await Promise.all([
const [models, pricing, labs] = await Promise.all([
fetchCatalogPayload(modelCatalogSourceUrl),
fetchCatalogPayload(modelCatalogPricingUrl),
fetchLabCatalogPayload(modelCatalogLabSourceUrl),
])
return buildModelCatalog(models, pricing)
return buildModelCatalog(models, pricing, labs)
}, "getModelCatalog")
export function findModelCatalogEntry(catalog: ModelCatalog, model: string, lab?: string) {
@ -113,9 +115,9 @@ export function catalogSlug(value: string) {
.replace(/-{2,}/g, "-")
}
function buildModelCatalog(payload: unknown, pricingPayload?: unknown): ModelCatalog {
function buildModelCatalog(payload: unknown, pricingPayload?: unknown, labPayload?: unknown): ModelCatalog {
const costs = readCatalogCosts(pricingPayload)
const labDescriptions = readCatalogLabDescriptions(payload, pricingPayload)
const labDescriptions = readCatalogLabDescriptions(payload, pricingPayload, labPayload)
const models = readCatalogModels(payload)
.flatMap(readModelCatalogEntry)
.map((model) => ({
@ -191,7 +193,8 @@ function readCatalogLabDescriptions(...payloads: unknown[]) {
if (!description) return
const id = stringValue(value.id) ?? fallbackId
const name = stringValue(value.name)
const keys = [id, name]
const title = stringValue(value.title)
const keys = [id, name, title]
keys.forEach((key) => {
if (!key) return
descriptions.set(catalogLabSlug(key), description)
@ -226,6 +229,21 @@ async function fetchCatalogPayload(url: string) {
.catch(() => undefined)
}
async function fetchLabCatalogPayload(url: string) {
return fetch(url)
.then((response) => (response.ok ? response.text() : Promise.resolve("")))
.then(readLabSearchIndex)
.catch(() => undefined)
}
function readLabSearchIndex(html: string) {
const match = /<script[^>]*id=["']search-index["'][^>]*>([\s\S]*?)<\/script>/.exec(html)
if (!match) return undefined
const parsed = JSON.parse(match[1]) as unknown
if (!Array.isArray(parsed)) return undefined
return parsed.filter((item) => isRecord(item) && item.type === "lab")
}
function readCatalogCosts(payload: unknown) {
const costs = new Map<string, ModelCatalogCost>()
const add = (model: unknown, provider?: string) => {