From 77e51b0a32cf5458d6c50a4fb487b085142b748d Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 12 May 2026 23:19:23 -0400 Subject: [PATCH] zen: stat worker --- infra/console.ts | 1 + .../app/src/routes/zen/util/handler.ts | 3 ++- .../src/routes/zen/util/modelTpsLimiter.ts | 16 +++++++++++----- packages/console/function/src/stat.ts | 19 ++++++++++--------- sst-env.d.ts | 1 + sst.config.ts | 2 +- 6 files changed, 26 insertions(+), 16 deletions(-) diff --git a/infra/console.ts b/infra/console.ts index c247dfcdb2..56befe6268 100644 --- a/infra/console.ts +++ b/infra/console.ts @@ -301,4 +301,5 @@ new sst.cloudflare.x.SolidStart("Console", { export const stat = new sst.cloudflare.Worker("Stat", { handler: "packages/console/function/src/stat.ts", link: [database], + url: true, }) diff --git a/packages/console/app/src/routes/zen/util/handler.ts b/packages/console/app/src/routes/zen/util/handler.ts index 540dfe7e87..a550a6e4c6 100644 --- a/packages/console/app/src/routes/zen/util/handler.ts +++ b/packages/console/app/src/routes/zen/util/handler.ts @@ -320,6 +320,7 @@ export async function handler( await modelTpsLimiter?.track( providerInfo.id, providerInfo.model, + providerInfo.tpsGoal, timestampFirstByte, timestampLastByte, usageInfo, @@ -525,7 +526,7 @@ export async function handler( }) .filter((provider) => { 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 }) .map((provider) => { diff --git a/packages/console/app/src/routes/zen/util/modelTpsLimiter.ts b/packages/console/app/src/routes/zen/util/modelTpsLimiter.ts index 428272eecd..477d08ce68 100644 --- a/packages/console/app/src/routes/zen/util/modelTpsLimiter.ts +++ b/packages/console/app/src/routes/zen/util/modelTpsLimiter.ts @@ -5,7 +5,7 @@ import { UsageInfo } from "./provider/provider" export function createModelTpsLimiter(providers: { id: string; model: string; tpsGoal?: number }[]) { const tpsGoals = Object.fromEntries( 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) @@ -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) => { - const id = `${provider}/${model}` - if (!ids.includes(id)) return - const tpsGoal = tpsGoals[id] + track: async ( + provider: string, + model: string, + tpsGoal: number | undefined, + tsFirstByte: number, + tsLastByte: number, + usageInfo: UsageInfo, + ) => { if (!tpsGoal) return + const id = `${provider}/${model}/${tpsGoal}` + if (!ids.includes(id)) return if (tsFirstByte <= 0 || tsLastByte <= 0) return const tokens = usageInfo.outputTokens if (tokens <= 10) return diff --git a/packages/console/function/src/stat.ts b/packages/console/function/src/stat.ts index 078aabb519..9a1a1cc145 100644 --- a/packages/console/function/src/stat.ts +++ b/packages/console/function/src/stat.ts @@ -1,16 +1,17 @@ -import { WorkerEntrypoint } from "cloudflare:workers" import { and, Database, inArray } from "@opencode-ai/console-core/drizzle/index.js" import { ModelTpsRateLimitTable } from "@opencode-ai/console-core/schema/ip.sql.js" +type Entry = { provider: string; model: string; tps: number } type Result = Record -export default class Stat extends WorkerEntrypoint { - async fetch() { - return new Response("Not Found", { status: 404 }) - } +export default { + async fetch(request: Request) { + if (request.method !== "POST") return new Response("Method Not Allowed", { status: 405 }) - async getStats(ids: string[]): Promise { - if (ids.length === 0) return {} + const entries = (await request.json()) as Entry[] + 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) => parseInt( @@ -34,6 +35,6 @@ export default class Stat extends WorkerEntrypoint { result[row.id].qualify += row.qualify result[row.id].unqualify += row.unqualify } - return result - } + return Response.json(result) + }, } diff --git a/sst-env.d.ts b/sst-env.d.ts index a55dd4bb49..b75b4bd6e6 100644 --- a/sst-env.d.ts +++ b/sst-env.d.ts @@ -155,6 +155,7 @@ declare module "sst" { } "Stat": { "type": "sst.cloudflare.Worker" + "url": string } "Teams": { "type": "sst.cloudflare.SolidStart" diff --git a/sst.config.ts b/sst.config.ts index 2feb3ac248..4bf7cc6a8d 100644 --- a/sst.config.ts +++ b/sst.config.ts @@ -26,7 +26,7 @@ export default $config({ } return { - STAT_WORKER_NAME: stat.nodes.worker.scriptName, + StatWorkerUrl: stat.url, } }, })