zen: stat worker

This commit is contained in:
Frank
2026-05-12 23:19:23 -04:00
parent 784796e27a
commit 77e51b0a32
6 changed files with 26 additions and 16 deletions

View File

@@ -301,4 +301,5 @@ new sst.cloudflare.x.SolidStart("Console", {
export const stat = new sst.cloudflare.Worker("Stat", { export const stat = new sst.cloudflare.Worker("Stat", {
handler: "packages/console/function/src/stat.ts", handler: "packages/console/function/src/stat.ts",
link: [database], link: [database],
url: true,
}) })

View File

@@ -320,6 +320,7 @@ export async function handler(
await modelTpsLimiter?.track( await modelTpsLimiter?.track(
providerInfo.id, providerInfo.id,
providerInfo.model, providerInfo.model,
providerInfo.tpsGoal,
timestampFirstByte, timestampFirstByte,
timestampLastByte, timestampLastByte,
usageInfo, usageInfo,
@@ -525,7 +526,7 @@ export async function handler(
}) })
.filter((provider) => { .filter((provider) => {
if (!provider.tpsGoal) return true if (!provider.tpsGoal) return true
const isLowTps = modelTpsLimits?.[`${provider.id}/${provider.model}`] ?? false const isLowTps = modelTpsLimits?.[`${provider.id}/${provider.model}/${provider.tpsGoal}`] ?? false
return !isLowTps return !isLowTps
}) })
.map((provider) => { .map((provider) => {

View File

@@ -5,7 +5,7 @@ import { UsageInfo } from "./provider/provider"
export function createModelTpsLimiter(providers: { id: string; model: string; tpsGoal?: number }[]) { export function createModelTpsLimiter(providers: { id: string; model: string; tpsGoal?: number }[]) {
const tpsGoals = Object.fromEntries( const tpsGoals = Object.fromEntries(
providers.flatMap((p) => { providers.flatMap((p) => {
return p.tpsGoal ? [[`${p.id}/${p.model}`, p.tpsGoal]] : [] return p.tpsGoal ? [[`${p.id}/${p.model}/${p.tpsGoal}`, p.tpsGoal]] : []
}), }),
) )
const ids = Object.keys(tpsGoals) const ids = Object.keys(tpsGoals)
@@ -56,11 +56,17 @@ export function createModelTpsLimiter(providers: { id: string; model: string; tp
}), }),
) )
}, },
track: async (provider: string, model: string, tsFirstByte: number, tsLastByte: number, usageInfo: UsageInfo) => { track: async (
const id = `${provider}/${model}` provider: string,
if (!ids.includes(id)) return model: string,
const tpsGoal = tpsGoals[id] tpsGoal: number | undefined,
tsFirstByte: number,
tsLastByte: number,
usageInfo: UsageInfo,
) => {
if (!tpsGoal) return if (!tpsGoal) return
const id = `${provider}/${model}/${tpsGoal}`
if (!ids.includes(id)) return
if (tsFirstByte <= 0 || tsLastByte <= 0) return if (tsFirstByte <= 0 || tsLastByte <= 0) return
const tokens = usageInfo.outputTokens const tokens = usageInfo.outputTokens
if (tokens <= 10) return if (tokens <= 10) return

View File

@@ -1,16 +1,17 @@
import { WorkerEntrypoint } from "cloudflare:workers"
import { and, Database, inArray } from "@opencode-ai/console-core/drizzle/index.js" import { and, Database, inArray } from "@opencode-ai/console-core/drizzle/index.js"
import { ModelTpsRateLimitTable } from "@opencode-ai/console-core/schema/ip.sql.js" import { ModelTpsRateLimitTable } from "@opencode-ai/console-core/schema/ip.sql.js"
type Entry = { provider: string; model: string; tps: number }
type Result = Record<string, { qualify: number; unqualify: number }> type Result = Record<string, { qualify: number; unqualify: number }>
export default class Stat extends WorkerEntrypoint { export default {
async fetch() { async fetch(request: Request) {
return new Response("Not Found", { status: 404 }) if (request.method !== "POST") return new Response("Method Not Allowed", { status: 405 })
}
async getStats(ids: string[]): Promise<Result> { const entries = (await request.json()) as Entry[]
if (ids.length === 0) return {} if (!Array.isArray(entries) || entries.length === 0) return Response.json({} satisfies Result)
const ids = entries.map((e) => `${e.provider}/${e.model}/${e.tps}`)
const toInterval = (date: Date) => const toInterval = (date: Date) =>
parseInt( parseInt(
@@ -34,6 +35,6 @@ export default class Stat extends WorkerEntrypoint {
result[row.id].qualify += row.qualify result[row.id].qualify += row.qualify
result[row.id].unqualify += row.unqualify result[row.id].unqualify += row.unqualify
} }
return result return Response.json(result)
} },
} }

1
sst-env.d.ts vendored
View File

@@ -155,6 +155,7 @@ declare module "sst" {
} }
"Stat": { "Stat": {
"type": "sst.cloudflare.Worker" "type": "sst.cloudflare.Worker"
"url": string
} }
"Teams": { "Teams": {
"type": "sst.cloudflare.SolidStart" "type": "sst.cloudflare.SolidStart"

View File

@@ -26,7 +26,7 @@ export default $config({
} }
return { return {
STAT_WORKER_NAME: stat.nodes.worker.scriptName, StatWorkerUrl: stat.url,
} }
}, },
}) })