|
|
|
@@ -4,7 +4,7 @@ import { Resource } from "sst/resource"
|
|
|
|
|
import { DatabaseError } from "../database"
|
|
|
|
|
import type { GeoStatMetric } from "./geo"
|
|
|
|
|
import { ModelStatRepo, type ModelStatMetric } from "./model"
|
|
|
|
|
import type { ProviderStatMetric } from "./provider"
|
|
|
|
|
import { statProvider } from "./model-normalization"
|
|
|
|
|
import { DATA_SITE_TIERS, normalizeTier } from "./stat"
|
|
|
|
|
|
|
|
|
|
export type UsageProduct = "All Users" | "Zen" | "Go" | "Enterprise"
|
|
|
|
@@ -140,10 +140,6 @@ type StatMetricRow = Omit<ModelStatMetric, "updatedAt"> & {
|
|
|
|
|
periodStart: number
|
|
|
|
|
updatedAt: number
|
|
|
|
|
}
|
|
|
|
|
type ProviderMetricRow = Omit<ProviderStatMetric, "updatedAt"> & {
|
|
|
|
|
periodStart: number
|
|
|
|
|
updatedAt: number
|
|
|
|
|
}
|
|
|
|
|
type GeoMetricRow = Omit<GeoStatMetric, "updatedAt"> & {
|
|
|
|
|
periodStart: number
|
|
|
|
|
updatedAt: number
|
|
|
|
@@ -171,12 +167,8 @@ type RawRow = Record<string, unknown>
|
|
|
|
|
export function getStatsHomeData(): Effect.Effect<StatsHomeData, StatsDataError> {
|
|
|
|
|
return Effect.tryPromise({
|
|
|
|
|
try: async () => {
|
|
|
|
|
const [modelRows, providerRows, geoRows] = await Promise.all([
|
|
|
|
|
listModelDaily(),
|
|
|
|
|
listProviderDaily(),
|
|
|
|
|
listGeoDaily(),
|
|
|
|
|
])
|
|
|
|
|
return buildStatsHomeData(modelRows, providerRows, geoRows)
|
|
|
|
|
const [modelRows, geoRows] = await Promise.all([listModelDaily(), listGeoDaily()])
|
|
|
|
|
return buildStatsHomeData(modelRows, geoRows)
|
|
|
|
|
},
|
|
|
|
|
catch: (cause) => new StatsDataError(cause),
|
|
|
|
|
})
|
|
|
|
@@ -241,23 +233,6 @@ async function listModelDaily(): Promise<ModelStatMetric[]> {
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function listProviderDaily(): Promise<ProviderStatMetric[]> {
|
|
|
|
|
return (
|
|
|
|
|
await queryRows(
|
|
|
|
|
`select period_key, updated_at, tier, provider, total_tokens from provider_stat
|
|
|
|
|
where grain = 'day' and client = 'all' and source = 'all'
|
|
|
|
|
and tier in (${SITE_TIER_PLACEHOLDERS}) order by period_key`,
|
|
|
|
|
DATA_SITE_TIERS,
|
|
|
|
|
)
|
|
|
|
|
).map((row) => ({
|
|
|
|
|
periodKey: stringValue(row.period_key),
|
|
|
|
|
updatedAt: dateValue(row.updated_at),
|
|
|
|
|
tier: stringValue(row.tier),
|
|
|
|
|
provider: stringValue(row.provider),
|
|
|
|
|
totalTokens: numberValue(row.total_tokens),
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function listGeoDaily(opts?: { provider?: string; model?: string }): Promise<GeoStatMetric[]> {
|
|
|
|
|
const scope =
|
|
|
|
|
opts?.model && opts.provider
|
|
|
|
@@ -334,15 +309,10 @@ export const getStatsModelComparisonData = (
|
|
|
|
|
{ provider: secondProvider, model: secondModel },
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
function buildStatsHomeData(
|
|
|
|
|
modelRows: ModelStatMetric[],
|
|
|
|
|
providerRows: ProviderStatMetric[],
|
|
|
|
|
geoRows: GeoStatMetric[],
|
|
|
|
|
): StatsHomeData {
|
|
|
|
|
function buildStatsHomeData(modelRows: ModelStatMetric[], geoRows: GeoStatMetric[]): StatsHomeData {
|
|
|
|
|
const normalized = modelRows.flatMap(normalizeStatRow)
|
|
|
|
|
const providers = providerRows.flatMap(normalizeProviderRow)
|
|
|
|
|
const geo = geoRows.flatMap(normalizeGeoRow)
|
|
|
|
|
const periods = [...normalized, ...providers, ...geo]
|
|
|
|
|
const periods = [...normalized, ...geo]
|
|
|
|
|
if (periods.length === 0) return emptyStatsHomeData()
|
|
|
|
|
|
|
|
|
|
const earliest = Math.min(...periods.map((row) => row.periodStart))
|
|
|
|
@@ -377,7 +347,7 @@ function buildStatsHomeData(
|
|
|
|
|
leaderboard: createUsageProductRecord((product) =>
|
|
|
|
|
createRangeRecord((range) => buildLeaderboard(normalized, product, getWindow("1W", earliest, latest))),
|
|
|
|
|
),
|
|
|
|
|
market: createRangeRecord((range) => buildMarketShare(providers, "Go", range, getWindow(range, earliest, latest))),
|
|
|
|
|
market: createRangeRecord((range) => buildMarketShare(normalized, "Go", range, getWindow(range, earliest, latest))),
|
|
|
|
|
tokenCost: createTokenProductRecord((product) =>
|
|
|
|
|
buildTokenCost(normalized, product, getWindow("1W", earliest, latest)),
|
|
|
|
|
),
|
|
|
|
@@ -602,15 +572,20 @@ function buildLeaderboard(rows: StatMetricRow[], product: UsageProduct, rankWind
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function buildMarketShare(rows: ProviderMetricRow[], product: UsageProduct, range: UsageRange, window: DateWindow) {
|
|
|
|
|
function buildMarketShare(rows: StatMetricRow[], product: UsageProduct, range: UsageRange, window: DateWindow) {
|
|
|
|
|
const providerOrder = aggregateByProvider(rowsForProduct(rows, product, window.start, window.end))
|
|
|
|
|
.filter((item) => item.provider !== "unknown")
|
|
|
|
|
.toSorted((a, b) => b.tokens - a.tokens || a.provider.localeCompare(b.provider))
|
|
|
|
|
.slice(0, 8)
|
|
|
|
|
.map((item) => item.provider)
|
|
|
|
|
|
|
|
|
|
return createBuckets(window, range).flatMap((bucket) => {
|
|
|
|
|
const total = aggregateByProvider(rowsForProduct(rows, product, bucket.start, bucket.end)).toSorted(
|
|
|
|
|
(a, b) => b.tokens - a.tokens,
|
|
|
|
|
)
|
|
|
|
|
const total = aggregateByProvider(rowsForProduct(rows, product, bucket.start, bucket.end))
|
|
|
|
|
const totalTokens = total.reduce((sum, item) => sum + item.tokens, 0)
|
|
|
|
|
if (totalTokens === 0) return []
|
|
|
|
|
|
|
|
|
|
const authors = total.slice(0, 8)
|
|
|
|
|
const byProvider = new Map(total.map((item) => [item.provider, item.tokens]))
|
|
|
|
|
const authors = providerOrder.map((provider) => ({ provider, tokens: byProvider.get(provider) ?? 0 }))
|
|
|
|
|
const knownTokens = authors.reduce((sum, item) => sum + item.tokens, 0)
|
|
|
|
|
const withOther = [...authors, { provider: "Other", tokens: Math.max(totalTokens - knownTokens, 0) }].filter(
|
|
|
|
|
(item) => item.tokens > 0,
|
|
|
|
@@ -773,7 +748,7 @@ function aggregateByModelName(rows: StatMetricRow[]) {
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function aggregateByProvider(rows: ProviderMetricRow[]) {
|
|
|
|
|
function aggregateByProvider(rows: { provider: string; totalTokens: number }[]) {
|
|
|
|
|
return Object.values(
|
|
|
|
|
rows.reduce<Record<string, { provider: string; tokens: number }>>((result, row) => {
|
|
|
|
|
result[row.provider] = {
|
|
|
|
@@ -917,27 +892,12 @@ function normalizeStatRow(row: ModelStatMetric): StatMetricRow[] {
|
|
|
|
|
periodStart,
|
|
|
|
|
updatedAt,
|
|
|
|
|
tier: normalizeTier(row.tier),
|
|
|
|
|
provider: row.provider || "unknown",
|
|
|
|
|
provider: statProvider(row.model, undefined, row.provider) || "unknown",
|
|
|
|
|
model: row.model || "unknown",
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function normalizeProviderRow(row: ProviderStatMetric): ProviderMetricRow[] {
|
|
|
|
|
const periodStart = periodKeyTime(row.periodKey)
|
|
|
|
|
const updatedAt = dateTime(row.updatedAt)
|
|
|
|
|
if (!Number.isFinite(periodStart) || !Number.isFinite(updatedAt)) return []
|
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
...row,
|
|
|
|
|
periodStart,
|
|
|
|
|
updatedAt,
|
|
|
|
|
tier: normalizeTier(row.tier),
|
|
|
|
|
provider: row.provider || "unknown",
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function normalizeGeoRow(row: GeoStatMetric): GeoMetricRow[] {
|
|
|
|
|
const periodStart = periodKeyTime(row.periodKey)
|
|
|
|
|
const updatedAt = dateTime(row.updatedAt)
|
|
|
|
@@ -948,7 +908,7 @@ function normalizeGeoRow(row: GeoStatMetric): GeoMetricRow[] {
|
|
|
|
|
periodStart,
|
|
|
|
|
updatedAt,
|
|
|
|
|
tier: normalizeTier(row.tier),
|
|
|
|
|
provider: row.provider || "all",
|
|
|
|
|
provider: row.provider === "all" ? "all" : statProvider(row.model, undefined, row.provider) || "unknown",
|
|
|
|
|
model: row.model || "all",
|
|
|
|
|
country: row.country || "ZZ",
|
|
|
|
|
continent: row.continent || "",
|
|
|
|
@@ -987,6 +947,7 @@ function formatProvider(provider: string) {
|
|
|
|
|
deepseek: "DeepSeek",
|
|
|
|
|
google: "Google",
|
|
|
|
|
minimax: "MiniMax",
|
|
|
|
|
meta: "Meta",
|
|
|
|
|
moonshot: "Moonshot",
|
|
|
|
|
moonshotai: "Moonshot",
|
|
|
|
|
nvidia: "NVIDIA",
|
|
|
|
|