Something went wrong. Try again.
opencode v2 mirror
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156import { z } from "zod"import { fn } from "./util/fn"import { centsToMicroCents } from "./util/price"import { getWeekBounds, getMonthlyBounds } from "./util/date"import { Resource } from "@opencode/console-resource"
export namespace Subscription { const LimitsSchema = z.object({ free: z.object({ promoTokens: z.number().int(), dailyRequests: z.number().int(), dailyRequestsFallback: z.number().int(), checkHeaders: z.record(z.string(), z.string()), }), lite: z.object({ rollingLimit: z.number().int(), rollingWindow: z.number().int(), weeklyLimit: z.number().int(), monthlyLimit: z.number().int(), }), black: z.object({ "20": z.object({ fixedLimit: z.number().int(), rollingLimit: z.number().int(), rollingWindow: z.number().int(), }), "100": z.object({ fixedLimit: z.number().int(), rollingLimit: z.number().int(), rollingWindow: z.number().int(), }), "200": z.object({ fixedLimit: z.number().int(), rollingLimit: z.number().int(), rollingWindow: z.number().int(), }), }), })
export const validate = fn(LimitsSchema, (input) => { return input })
export const getLimits = fn(z.void(), () => { const json = JSON.parse(Resource.ZEN_LIMITS.value) return LimitsSchema.parse(json) })
export const getFreeLimits = fn(z.void(), () => { return getLimits()["free"] })
export const analyzeRollingUsage = fn( z.object({ limit: z.number().int(), window: z.number().int(), usage: z.number().int(), timeUpdated: z.date(), }), ({ limit, window, usage, timeUpdated }) => { const now = new Date() const rollingWindowMs = window * 3600 * 1000 const rollingLimitInMicroCents = centsToMicroCents(limit * 100) const windowStart = new Date(now.getTime() - rollingWindowMs) if (timeUpdated < windowStart) { return { status: "ok" as const, resetInSec: window * 3600, usagePercent: 0, } }
const windowEnd = new Date(timeUpdated.getTime() + rollingWindowMs) if (usage < rollingLimitInMicroCents) { return { status: "ok" as const, resetInSec: Math.ceil((windowEnd.getTime() - now.getTime()) / 1000), usagePercent: Math.floor(Math.min(100, (usage / rollingLimitInMicroCents) * 100)), } } return { status: "rate-limited" as const, resetInSec: Math.ceil((windowEnd.getTime() - now.getTime()) / 1000), usagePercent: 100, } }, )
export const analyzeWeeklyUsage = fn( z.object({ limit: z.number().int(), usage: z.number().int(), timeUpdated: z.date(), }), ({ limit, usage, timeUpdated }) => { const now = new Date() const week = getWeekBounds(now) const fixedLimitInMicroCents = centsToMicroCents(limit * 100) if (timeUpdated < week.start) { return { status: "ok" as const, resetInSec: Math.ceil((week.end.getTime() - now.getTime()) / 1000), usagePercent: 0, } } if (usage < fixedLimitInMicroCents) { return { status: "ok" as const, resetInSec: Math.ceil((week.end.getTime() - now.getTime()) / 1000), usagePercent: Math.floor(Math.min(100, (usage / fixedLimitInMicroCents) * 100)), } }
return { status: "rate-limited" as const, resetInSec: Math.ceil((week.end.getTime() - now.getTime()) / 1000), usagePercent: 100, } }, )
export const analyzeMonthlyUsage = fn( z.object({ limit: z.number().int(), usage: z.number().int(), timeUpdated: z.date(), timeSubscribed: z.date(), }), ({ limit, usage, timeUpdated, timeSubscribed }) => { const now = new Date() const month = getMonthlyBounds(now, timeSubscribed) const fixedLimitInMicroCents = centsToMicroCents(limit * 100) if (timeUpdated < month.start) { return { status: "ok" as const, resetInSec: Math.ceil((month.end.getTime() - now.getTime()) / 1000), usagePercent: 0, } } if (usage < fixedLimitInMicroCents) { return { status: "ok" as const, resetInSec: Math.ceil((month.end.getTime() - now.getTime()) / 1000), usagePercent: Math.floor(Math.min(100, (usage / fixedLimitInMicroCents) * 100)), } }
return { status: "rate-limited" as const, resetInSec: Math.ceil((month.end.getTime() - now.getTime()) / 1000), usagePercent: 100, } }, )}