Skip to content

Commit 57120e6

Browse files
author
Frank
committed
Zen: sync
1 parent 11efda3 commit 57120e6

14 files changed

Lines changed: 109 additions & 50 deletions

File tree

infra/console.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ const ZEN_MODELS = [
102102
new sst.Secret("ZEN_MODELS2"),
103103
new sst.Secret("ZEN_MODELS3"),
104104
new sst.Secret("ZEN_MODELS4"),
105+
new sst.Secret("ZEN_MODELS5"),
105106
]
106107
const STRIPE_SECRET_KEY = new sst.Secret("STRIPE_SECRET_KEY")
107108
const AUTH_API_URL = new sst.Linkable("AUTH_API_URL", {

packages/console/app/src/routes/workspace/[id]/model-section.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,12 @@ const getModelsInfo = query(async (workspaceID: string) => {
4343
const pA = getPriority(idA)
4444
const pB = getPriority(idB)
4545
if (pA !== pB) return pA - pB
46-
return modelA.name.localeCompare(modelB.name)
46+
47+
const modelAName = Array.isArray(modelA) ? modelA[0].name : modelA.name
48+
const modelBName = Array.isArray(modelB) ? modelB[0].name : modelB.name
49+
return modelAName.localeCompare(modelBName)
4750
})
48-
.map(([id, model]) => ({ id, name: model.name })),
51+
.map(([id, model]) => ({ id, name: Array.isArray(model) ? model[0].name : model.name })),
4952
disabled: await Model.listDisabled(),
5053
}
5154
}, workspaceID)

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,17 @@ export async function handler(
5757
const sessionId = input.request.headers.get("x-opencode-session") ?? ""
5858
const requestId = input.request.headers.get("x-opencode-request") ?? ""
5959
const projectId = input.request.headers.get("x-opencode-project") ?? ""
60+
const ocClient = input.request.headers.get("x-opencode-client") ?? ""
6061
logger.metric({
6162
is_tream: isStream,
6263
session: sessionId,
6364
request: requestId,
65+
client: ocClient,
6466
})
6567
const zenData = ZenData.list()
6668
const modelInfo = validateModel(zenData, model)
6769
const dataDumper = createDataDumper(sessionId, requestId, projectId)
68-
const trialLimiter = createTrialLimiter(modelInfo.trial?.limit, ip)
70+
const trialLimiter = createTrialLimiter(modelInfo.trial, ip, ocClient)
6971
const isTrial = await trialLimiter?.isTrial()
7072
const rateLimiter = createRateLimiter(modelInfo.id, modelInfo.rateLimit, ip)
7173
await rateLimiter?.check()
@@ -286,11 +288,14 @@ export async function handler(
286288
}
287289

288290
function validateModel(zenData: ZenData, reqModel: string) {
289-
if (!(reqModel in zenData.models)) {
290-
throw new ModelError(`Model ${reqModel} not supported`)
291-
}
291+
if (!(reqModel in zenData.models)) throw new ModelError(`Model ${reqModel} not supported`)
292+
292293
const modelId = reqModel as keyof typeof zenData.models
293-
const modelData = zenData.models[modelId]
294+
const modelData = Array.isArray(zenData.models[modelId])
295+
? zenData.models[modelId].find((model) => opts.format === model.formatFilter)
296+
: zenData.models[modelId]
297+
298+
if (!modelData) throw new ModelError(`Model ${reqModel} not supported for format ${opts.format}`)
294299

295300
logger.metric({ model: modelId })
296301

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import { Database, eq, sql } from "@opencode-ai/console-core/drizzle/index.js"
22
import { IpTable } from "@opencode-ai/console-core/schema/ip.sql.js"
33
import { UsageInfo } from "./provider/provider"
4+
import { ZenData } from "@opencode-ai/console-core/model.js"
45

5-
export function createTrialLimiter(limit: number | undefined, ip: string) {
6-
if (!limit) return
6+
export function createTrialLimiter(trial: ZenData.Trial | undefined, ip: string, client: string) {
7+
if (!trial) return
78
if (!ip) return
89

9-
let trial: boolean
10+
const limit =
11+
trial.limits.find((limit) => limit.client === client)?.limit ??
12+
trial.limits.find((limit) => limit.client === undefined)?.limit
13+
if (!limit) return
14+
15+
let _isTrial: boolean
1016

1117
return {
1218
isTrial: async () => {
@@ -20,11 +26,11 @@ export function createTrialLimiter(limit: number | undefined, ip: string) {
2026
.then((rows) => rows[0]),
2127
)
2228

23-
trial = (data?.usage ?? 0) < limit
24-
return trial
29+
_isTrial = (data?.usage ?? 0) < limit
30+
return _isTrial
2531
},
2632
track: async (usageInfo: UsageInfo) => {
27-
if (!trial) return
33+
if (!_isTrial) return
2834
const usage =
2935
usageInfo.inputTokens +
3036
usageInfo.outputTokens +

packages/console/core/script/promote-models.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,19 @@ const value1 = lines.find((line) => line.startsWith("ZEN_MODELS1"))?.split("=")[
1616
const value2 = lines.find((line) => line.startsWith("ZEN_MODELS2"))?.split("=")[1]
1717
const value3 = lines.find((line) => line.startsWith("ZEN_MODELS3"))?.split("=")[1]
1818
const value4 = lines.find((line) => line.startsWith("ZEN_MODELS4"))?.split("=")[1]
19+
const value5 = lines.find((line) => line.startsWith("ZEN_MODELS5"))?.split("=")[1]
1920
if (!value1) throw new Error("ZEN_MODELS1 not found")
2021
if (!value2) throw new Error("ZEN_MODELS2 not found")
2122
if (!value3) throw new Error("ZEN_MODELS3 not found")
2223
if (!value4) throw new Error("ZEN_MODELS4 not found")
24+
if (!value5) throw new Error("ZEN_MODELS5 not found")
2325

2426
// validate value
25-
ZenData.validate(JSON.parse(value1 + value2 + value3 + value4))
27+
ZenData.validate(JSON.parse(value1 + value2 + value3 + value4 + value5))
2628

2729
// update the secret
2830
await $`bun sst secret set ZEN_MODELS1 ${value1} --stage ${stage}`
2931
await $`bun sst secret set ZEN_MODELS2 ${value2} --stage ${stage}`
3032
await $`bun sst secret set ZEN_MODELS3 ${value3} --stage ${stage}`
3133
await $`bun sst secret set ZEN_MODELS4 ${value4} --stage ${stage}`
34+
await $`bun sst secret set ZEN_MODELS5 ${value5} --stage ${stage}`

packages/console/core/script/pull-models.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,19 @@ const value1 = lines.find((line) => line.startsWith("ZEN_MODELS1"))?.split("=")[
1616
const value2 = lines.find((line) => line.startsWith("ZEN_MODELS2"))?.split("=")[1]
1717
const value3 = lines.find((line) => line.startsWith("ZEN_MODELS3"))?.split("=")[1]
1818
const value4 = lines.find((line) => line.startsWith("ZEN_MODELS4"))?.split("=")[1]
19+
const value5 = lines.find((line) => line.startsWith("ZEN_MODELS5"))?.split("=")[1]
1920
if (!value1) throw new Error("ZEN_MODELS1 not found")
2021
if (!value2) throw new Error("ZEN_MODELS2 not found")
2122
if (!value3) throw new Error("ZEN_MODELS3 not found")
2223
if (!value4) throw new Error("ZEN_MODELS4 not found")
24+
if (!value5) throw new Error("ZEN_MODELS5 not found")
2325

2426
// validate value
25-
ZenData.validate(JSON.parse(value1 + value2 + value3 + value4))
27+
ZenData.validate(JSON.parse(value1 + value2 + value3 + value4 + value5))
2628

2729
// update the secret
2830
await $`bun sst secret set ZEN_MODELS1 ${value1}`
2931
await $`bun sst secret set ZEN_MODELS2 ${value2}`
3032
await $`bun sst secret set ZEN_MODELS3 ${value3}`
3133
await $`bun sst secret set ZEN_MODELS4 ${value4}`
34+
await $`bun sst secret set ZEN_MODELS5 ${value5}`

packages/console/core/script/update-models.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@ const oldValue1 = lines.find((line) => line.startsWith("ZEN_MODELS1"))?.split("=
1414
const oldValue2 = lines.find((line) => line.startsWith("ZEN_MODELS2"))?.split("=")[1]
1515
const oldValue3 = lines.find((line) => line.startsWith("ZEN_MODELS3"))?.split("=")[1]
1616
const oldValue4 = lines.find((line) => line.startsWith("ZEN_MODELS4"))?.split("=")[1]
17+
const oldValue5 = lines.find((line) => line.startsWith("ZEN_MODELS5"))?.split("=")[1]
1718
if (!oldValue1) throw new Error("ZEN_MODELS1 not found")
1819
if (!oldValue2) throw new Error("ZEN_MODELS2 not found")
1920
if (!oldValue3) throw new Error("ZEN_MODELS3 not found")
2021
if (!oldValue4) throw new Error("ZEN_MODELS4 not found")
22+
if (!oldValue5) throw new Error("ZEN_MODELS5 not found")
2123

2224
// store the prettified json to a temp file
2325
const filename = `models-${Date.now()}.json`
2426
const tempFile = Bun.file(path.join(os.tmpdir(), filename))
25-
await tempFile.write(JSON.stringify(JSON.parse(oldValue1 + oldValue2 + oldValue3 + oldValue4), null, 2))
27+
await tempFile.write(JSON.stringify(JSON.parse(oldValue1 + oldValue2 + oldValue3 + oldValue4 + oldValue5), null, 2))
2628
console.log("tempFile", tempFile.name)
2729

2830
// open temp file in vim and read the file on close
@@ -31,12 +33,15 @@ const newValue = JSON.stringify(JSON.parse(await tempFile.text()))
3133
ZenData.validate(JSON.parse(newValue))
3234

3335
// update the secret
34-
const chunk = Math.ceil(newValue.length / 4)
36+
const chunk = Math.ceil(newValue.length / 5)
3537
const newValue1 = newValue.slice(0, chunk)
3638
const newValue2 = newValue.slice(chunk, chunk * 2)
3739
const newValue3 = newValue.slice(chunk * 2, chunk * 3)
38-
const newValue4 = newValue.slice(chunk * 3)
40+
const newValue4 = newValue.slice(chunk * 3, chunk * 4)
41+
const newValue5 = newValue.slice(chunk * 4)
42+
3943
await $`bun sst secret set ZEN_MODELS1 ${newValue1}`
4044
await $`bun sst secret set ZEN_MODELS2 ${newValue2}`
4145
await $`bun sst secret set ZEN_MODELS3 ${newValue3}`
4246
await $`bun sst secret set ZEN_MODELS4 ${newValue4}`
47+
await $`bun sst secret set ZEN_MODELS5 ${newValue5}`

packages/console/core/src/model.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,17 @@ import { Resource } from "@opencode-ai/console-resource"
99

1010
export namespace ZenData {
1111
const FormatSchema = z.enum(["anthropic", "google", "openai", "oa-compat"])
12+
const TrialSchema = z.object({
13+
provider: z.string(),
14+
limits: z.array(
15+
z.object({
16+
limit: z.number(),
17+
client: z.enum(["cli", "desktop"]).optional(),
18+
}),
19+
),
20+
})
1221
export type Format = z.infer<typeof FormatSchema>
22+
export type Trial = z.infer<typeof TrialSchema>
1323

1424
const ModelCostSchema = z.object({
1525
input: z.number(),
@@ -26,12 +36,7 @@ export namespace ZenData {
2636
allowAnonymous: z.boolean().optional(),
2737
byokProvider: z.enum(["openai", "anthropic", "google"]).optional(),
2838
stickyProvider: z.boolean().optional(),
29-
trial: z
30-
.object({
31-
limit: z.number(),
32-
provider: z.string(),
33-
})
34-
.optional(),
39+
trial: TrialSchema.optional(),
3540
rateLimit: z.number().optional(),
3641
fallbackProvider: z.string().optional(),
3742
providers: z.array(
@@ -53,7 +58,7 @@ export namespace ZenData {
5358
})
5459

5560
const ModelsSchema = z.object({
56-
models: z.record(z.string(), ModelSchema),
61+
models: z.record(z.string(), z.union([ModelSchema, z.array(ModelSchema.extend({ formatFilter: FormatSchema }))])),
5762
providers: z.record(z.string(), ProviderSchema),
5863
})
5964

@@ -63,7 +68,11 @@ export namespace ZenData {
6368

6469
export const list = fn(z.void(), () => {
6570
const json = JSON.parse(
66-
Resource.ZEN_MODELS1.value + Resource.ZEN_MODELS2.value + Resource.ZEN_MODELS3.value + Resource.ZEN_MODELS4.value,
71+
Resource.ZEN_MODELS1.value +
72+
Resource.ZEN_MODELS2.value +
73+
Resource.ZEN_MODELS3.value +
74+
Resource.ZEN_MODELS4.value +
75+
Resource.ZEN_MODELS5.value,
6776
)
6877
return ModelsSchema.parse(json)
6978
})

packages/console/core/sst-env.d.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,6 @@ declare module "sst" {
5050
"type": "sst.sst.Secret"
5151
"value": string
5252
}
53-
"Enterprise": {
54-
"type": "sst.cloudflare.SolidStart"
55-
"url": string
56-
}
5753
"GITHUB_APP_ID": {
5854
"type": "sst.sst.Secret"
5955
"value": string
@@ -94,6 +90,10 @@ declare module "sst" {
9490
"type": "sst.sst.Linkable"
9591
"value": string
9692
}
93+
"Teams": {
94+
"type": "sst.cloudflare.SolidStart"
95+
"url": string
96+
}
9797
"Web": {
9898
"type": "sst.cloudflare.Astro"
9999
"url": string
@@ -114,6 +114,10 @@ declare module "sst" {
114114
"type": "sst.sst.Secret"
115115
"value": string
116116
}
117+
"ZEN_MODELS5": {
118+
"type": "sst.sst.Secret"
119+
"value": string
120+
}
117121
}
118122
}
119123
// cloudflare

packages/console/function/sst-env.d.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,6 @@ declare module "sst" {
5050
"type": "sst.sst.Secret"
5151
"value": string
5252
}
53-
"Enterprise": {
54-
"type": "sst.cloudflare.SolidStart"
55-
"url": string
56-
}
5753
"GITHUB_APP_ID": {
5854
"type": "sst.sst.Secret"
5955
"value": string
@@ -94,6 +90,10 @@ declare module "sst" {
9490
"type": "sst.sst.Linkable"
9591
"value": string
9692
}
93+
"Teams": {
94+
"type": "sst.cloudflare.SolidStart"
95+
"url": string
96+
}
9797
"Web": {
9898
"type": "sst.cloudflare.Astro"
9999
"url": string
@@ -114,6 +114,10 @@ declare module "sst" {
114114
"type": "sst.sst.Secret"
115115
"value": string
116116
}
117+
"ZEN_MODELS5": {
118+
"type": "sst.sst.Secret"
119+
"value": string
120+
}
117121
}
118122
}
119123
// cloudflare

0 commit comments

Comments
 (0)