Skip to content

Commit 4850ecc

Browse files
authored
zen: rate limit (#11735)
1 parent 43354ee commit 4850ecc

2 files changed

Lines changed: 20 additions & 4 deletions

File tree

packages/console/app/src/routes/zen/util/rateLimiter.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ import { Database, eq, and, sql, inArray } from "@opencode-ai/console-core/drizz
22
import { IpRateLimitTable } from "@opencode-ai/console-core/schema/ip.sql.js"
33
import { RateLimitError } from "./error"
44
import { logger } from "./logger"
5+
import { ZenData } from "@opencode-ai/console-core/model.js"
56

6-
export function createRateLimiter(limit: number | undefined, rawIp: string) {
7+
export function createRateLimiter(limit: ZenData.RateLimit | undefined, rawIp: string) {
78
if (!limit) return
89

910
const ip = !rawIp.length ? "unknown" : rawIp
1011
const now = Date.now()
11-
const intervals = [buildYYYYMMDDHH(now), buildYYYYMMDDHH(now - 3_600_000), buildYYYYMMDDHH(now - 7_200_000)]
12+
const intervals =
13+
limit.period === "day"
14+
? [buildYYYYMMDD(now)]
15+
: [buildYYYYMMDDHH(now), buildYYYYMMDDHH(now - 3_600_000), buildYYYYMMDDHH(now - 7_200_000)]
1216

1317
return {
1418
track: async () => {
@@ -28,11 +32,18 @@ export function createRateLimiter(limit: number | undefined, rawIp: string) {
2832
)
2933
const total = rows.reduce((sum, r) => sum + r.count, 0)
3034
logger.debug(`rate limit total: ${total}`)
31-
if (total >= limit) throw new RateLimitError(`Rate limit exceeded. Please try again later.`)
35+
if (total >= limit.value) throw new RateLimitError(`Rate limit exceeded. Please try again later.`)
3236
},
3337
}
3438
}
3539

40+
function buildYYYYMMDD(timestamp: number) {
41+
return new Date(timestamp)
42+
.toISOString()
43+
.replace(/[^0-9]/g, "")
44+
.substring(0, 8)
45+
}
46+
3647
function buildYYYYMMDDHH(timestamp: number) {
3748
return new Date(timestamp)
3849
.toISOString()

packages/console/core/src/model.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ export namespace ZenData {
1818
}),
1919
),
2020
})
21+
const RateLimitSchema = z.object({
22+
period: z.enum(["day", "rolling"]),
23+
value: z.number().int(),
24+
})
2125
export type Format = z.infer<typeof FormatSchema>
2226
export type Trial = z.infer<typeof TrialSchema>
27+
export type RateLimit = z.infer<typeof RateLimitSchema>
2328

2429
const ModelCostSchema = z.object({
2530
input: z.number(),
@@ -37,7 +42,7 @@ export namespace ZenData {
3742
byokProvider: z.enum(["openai", "anthropic", "google"]).optional(),
3843
stickyProvider: z.enum(["strict", "prefer"]).optional(),
3944
trial: TrialSchema.optional(),
40-
rateLimit: z.number().optional(),
45+
rateLimit: RateLimitSchema.optional(),
4146
fallbackProvider: z.string().optional(),
4247
providers: z.array(
4348
z.object({

0 commit comments

Comments
 (0)