Skip to content

Commit 3b2a2c4

Browse files
committed
sync zen
1 parent 6706358 commit 3b2a2c4

2 files changed

Lines changed: 67 additions & 8 deletions

File tree

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export async function handler(
106106
const zenData = ZenData.list(opts.modelList)
107107
const modelInfo = validateModel(zenData, model)
108108
const dataDumper = createDataDumper(sessionId, requestId, projectId)
109-
const trialLimiter = createTrialLimiter(modelInfo.trialProviders, ip)
109+
const trialLimiter = createTrialLimiter(modelInfo.trialProvider, ip)
110110
const trialProviders = await trialLimiter?.check()
111111
const rateLimiter = createRateLimiter(
112112
modelInfo.id,
@@ -392,7 +392,7 @@ export async function handler(
392392
function validateModel(zenData: ZenData, reqModel: string) {
393393
if (!(reqModel in zenData.models)) throw new ModelError(t("zen.api.error.modelNotSupported", { model: reqModel }))
394394

395-
const modelId = reqModel as keyof typeof zenData.models
395+
const modelId = reqModel
396396
const modelData = Array.isArray(zenData.models[modelId])
397397
? zenData.models[modelId].find((model) => opts.format === model.formatFilter)
398398
: zenData.models[modelId]

packages/console/core/src/model.ts

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export namespace ZenData {
2626
allowAnonymous: z.boolean().optional(),
2727
byokProvider: z.enum(["openai", "anthropic", "google"]).optional(),
2828
stickyProvider: z.enum(["strict", "prefer"]).optional(),
29-
trialProviders: z.array(z.string()).optional(),
29+
trialProvider: z.string().optional(),
3030
trialEnded: z.boolean().optional(),
3131
fallbackProvider: z.string().optional(),
3232
rateLimit: z.number().optional(),
@@ -45,7 +45,7 @@ export namespace ZenData {
4545

4646
const ProviderSchema = z.object({
4747
api: z.string(),
48-
apiKey: z.string(),
48+
apiKey: z.union([z.string(), z.record(z.string(), z.string())]),
4949
format: FormatSchema.optional(),
5050
headerMappings: z.record(z.string(), z.string()).optional(),
5151
payloadModifier: z.record(z.string(), z.any()).optional(),
@@ -54,7 +54,10 @@ export namespace ZenData {
5454
})
5555

5656
const ModelsSchema = z.object({
57-
models: z.record(z.string(), z.union([ModelSchema, z.array(ModelSchema.extend({ formatFilter: FormatSchema }))])),
57+
zenModels: z.record(
58+
z.string(),
59+
z.union([ModelSchema, z.array(ModelSchema.extend({ formatFilter: FormatSchema }))]),
60+
),
5861
liteModels: z.record(
5962
z.string(),
6063
z.union([ModelSchema, z.array(ModelSchema.extend({ formatFilter: FormatSchema }))]),
@@ -99,10 +102,66 @@ export namespace ZenData {
99102
Resource.ZEN_MODELS29.value +
100103
Resource.ZEN_MODELS30.value,
101104
)
102-
const { models, liteModels, providers } = ModelsSchema.parse(json)
105+
const { zenModels, liteModels, providers } = ModelsSchema.parse(json)
106+
const compositeProviders = Object.fromEntries(
107+
Object.entries(providers).map(([id, provider]) => [
108+
id,
109+
typeof provider.apiKey === "string"
110+
? [{ id: id, key: provider.apiKey }]
111+
: Object.entries(provider.apiKey).map(([kid, key]) => ({
112+
id: `${id}.${kid}`,
113+
key,
114+
})),
115+
]),
116+
)
103117
return {
104-
models: modelList === "lite" ? liteModels : models,
105-
providers,
118+
providers: Object.fromEntries(
119+
Object.entries(providers).flatMap(([providerId, provider]) =>
120+
compositeProviders[providerId].map((p) => [p.id, { ...provider, apiKey: p.key }]),
121+
),
122+
),
123+
models: (() => {
124+
const normalize = (model: z.infer<typeof ModelSchema>) => {
125+
const composite = model.providers.find((p) => compositeProviders[p.id].length > 1)
126+
if (!composite)
127+
return {
128+
trialProvider: model.trialProvider ? [model.trialProvider] : undefined,
129+
}
130+
131+
const weightMulti = compositeProviders[composite.id].length
132+
133+
return {
134+
trialProvider: (() => {
135+
if (!model.trialProvider) return undefined
136+
if (model.trialProvider === composite.id) return compositeProviders[composite.id].map((p) => p.id)
137+
return [model.trialProvider]
138+
})(),
139+
providers: model.providers.flatMap((p) =>
140+
p.id === composite.id
141+
? compositeProviders[p.id].map((sub) => ({
142+
...p,
143+
id: sub.id,
144+
weight: p.weight ?? 1,
145+
}))
146+
: [
147+
{
148+
...p,
149+
weight: (p.weight ?? 1) * weightMulti,
150+
},
151+
],
152+
),
153+
}
154+
}
155+
156+
return Object.fromEntries(
157+
Object.entries(modelList === "lite" ? liteModels : zenModels).map(([modelId, model]) => {
158+
const n = Array.isArray(model)
159+
? model.map((m) => ({ ...m, ...normalize(m) }))
160+
: { ...model, ...normalize(model) }
161+
return [modelId, n]
162+
}),
163+
)
164+
})(),
106165
}
107166
})
108167
}

0 commit comments

Comments
 (0)