diff --git a/packages/console/app/src/routes/zen/util/handler.ts b/packages/console/app/src/routes/zen/util/handler.ts index 429ce0018..d0d8f172b 100644 --- a/packages/console/app/src/routes/zen/util/handler.ts +++ b/packages/console/app/src/routes/zen/util/handler.ts @@ -99,7 +99,13 @@ export async function handler( const dataDumper = createDataDumper(sessionId, requestId, projectId) const trialLimiter = createTrialLimiter(modelInfo.trialProvider, ip) const trialProvider = await trialLimiter?.check() - const rateLimiter = createRateLimiter(modelInfo.allowAnonymous, ip, input.request) + const rateLimiter = createRateLimiter( + modelInfo.id, + modelInfo.allowAnonymous, + modelInfo.rateLimit, + ip, + input.request, + ) await rateLimiter?.check() const stickyTracker = createStickyTracker(modelInfo.stickyProvider, sessionId) const stickyProvider = await stickyTracker?.get() diff --git a/packages/console/app/src/routes/zen/util/rateLimiter.ts b/packages/console/app/src/routes/zen/util/rateLimiter.ts index 019e68754..152ed9b8d 100644 --- a/packages/console/app/src/routes/zen/util/rateLimiter.ts +++ b/packages/console/app/src/routes/zen/util/rateLimiter.ts @@ -6,17 +6,25 @@ import { i18n } from "~/i18n" import { localeFromRequest } from "~/lib/language" import { Subscription } from "@opencode-ai/console-core/subscription.js" -export function createRateLimiter(allowAnonymous: boolean | undefined, rawIp: string, request: Request) { +export function createRateLimiter( + modelId: string, + allowAnonymous: boolean | undefined, + rateLimit: number | undefined, + rawIp: string, + request: Request, +) { if (!allowAnonymous) return const dict = i18n(localeFromRequest(request)) const limits = Subscription.getFreeLimits() const limitValue = - limits.checkHeader && !request.headers.get(limits.checkHeader) ? limits.fallbackValue : limits.dailyRequests + limits.checkHeader && !request.headers.get(limits.checkHeader) + ? limits.fallbackValue + : (rateLimit ?? limits.dailyRequests) const ip = !rawIp.length ? "unknown" : rawIp const now = Date.now() - const interval = buildYYYYMMDD(now) + const interval = rateLimit ? `${buildYYYYMMDD(now)}${modelId.substring(0, 2)}` : buildYYYYMMDD(now) return { track: async () => { diff --git a/packages/console/core/src/model.ts b/packages/console/core/src/model.ts index e4fa02249..223839bf1 100644 --- a/packages/console/core/src/model.ts +++ b/packages/console/core/src/model.ts @@ -28,6 +28,7 @@ export namespace ZenData { stickyProvider: z.enum(["strict", "prefer"]).optional(), trialProvider: z.string().optional(), fallbackProvider: z.string().optional(), + rateLimit: z.number().optional(), providers: z.array( z.object({ id: z.string(), diff --git a/packages/console/core/src/subscription.ts b/packages/console/core/src/subscription.ts index 9d6c3ce2b..994feaff0 100644 --- a/packages/console/core/src/subscription.ts +++ b/packages/console/core/src/subscription.ts @@ -8,6 +8,7 @@ export namespace Subscription { const LimitsSchema = z.object({ free: z.object({ promoTokens: z.number().int(), + newDailyRequests: z.number().int(), dailyRequests: z.number().int(), checkHeader: z.string(), fallbackValue: z.number().int(),