From 3b2a2c461debb1afebe65378f978389d06152e1e Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 14 Apr 2026 18:07:31 -0400 Subject: sync zen --- packages/console/core/src/model.ts | 71 ++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 6 deletions(-) (limited to 'packages/console/core/src/model.ts') diff --git a/packages/console/core/src/model.ts b/packages/console/core/src/model.ts index 3b2439431..b4149373f 100644 --- a/packages/console/core/src/model.ts +++ b/packages/console/core/src/model.ts @@ -26,7 +26,7 @@ export namespace ZenData { allowAnonymous: z.boolean().optional(), byokProvider: z.enum(["openai", "anthropic", "google"]).optional(), stickyProvider: z.enum(["strict", "prefer"]).optional(), - trialProviders: z.array(z.string()).optional(), + trialProvider: z.string().optional(), trialEnded: z.boolean().optional(), fallbackProvider: z.string().optional(), rateLimit: z.number().optional(), @@ -45,7 +45,7 @@ export namespace ZenData { const ProviderSchema = z.object({ api: z.string(), - apiKey: z.string(), + apiKey: z.union([z.string(), z.record(z.string(), z.string())]), format: FormatSchema.optional(), headerMappings: z.record(z.string(), z.string()).optional(), payloadModifier: z.record(z.string(), z.any()).optional(), @@ -54,7 +54,10 @@ export namespace ZenData { }) const ModelsSchema = z.object({ - models: z.record(z.string(), z.union([ModelSchema, z.array(ModelSchema.extend({ formatFilter: FormatSchema }))])), + zenModels: z.record( + z.string(), + z.union([ModelSchema, z.array(ModelSchema.extend({ formatFilter: FormatSchema }))]), + ), liteModels: z.record( z.string(), z.union([ModelSchema, z.array(ModelSchema.extend({ formatFilter: FormatSchema }))]), @@ -99,10 +102,66 @@ export namespace ZenData { Resource.ZEN_MODELS29.value + Resource.ZEN_MODELS30.value, ) - const { models, liteModels, providers } = ModelsSchema.parse(json) + const { zenModels, liteModels, providers } = ModelsSchema.parse(json) + const compositeProviders = Object.fromEntries( + Object.entries(providers).map(([id, provider]) => [ + id, + typeof provider.apiKey === "string" + ? [{ id: id, key: provider.apiKey }] + : Object.entries(provider.apiKey).map(([kid, key]) => ({ + id: `${id}.${kid}`, + key, + })), + ]), + ) return { - models: modelList === "lite" ? liteModels : models, - providers, + providers: Object.fromEntries( + Object.entries(providers).flatMap(([providerId, provider]) => + compositeProviders[providerId].map((p) => [p.id, { ...provider, apiKey: p.key }]), + ), + ), + models: (() => { + const normalize = (model: z.infer) => { + const composite = model.providers.find((p) => compositeProviders[p.id].length > 1) + if (!composite) + return { + trialProvider: model.trialProvider ? [model.trialProvider] : undefined, + } + + const weightMulti = compositeProviders[composite.id].length + + return { + trialProvider: (() => { + if (!model.trialProvider) return undefined + if (model.trialProvider === composite.id) return compositeProviders[composite.id].map((p) => p.id) + return [model.trialProvider] + })(), + providers: model.providers.flatMap((p) => + p.id === composite.id + ? compositeProviders[p.id].map((sub) => ({ + ...p, + id: sub.id, + weight: p.weight ?? 1, + })) + : [ + { + ...p, + weight: (p.weight ?? 1) * weightMulti, + }, + ], + ), + } + } + + return Object.fromEntries( + Object.entries(modelList === "lite" ? liteModels : zenModels).map(([modelId, model]) => { + const n = Array.isArray(model) + ? model.map((m) => ({ ...m, ...normalize(m) })) + : { ...model, ...normalize(model) } + return [modelId, n] + }), + ) + })(), } }) } -- cgit v1.2.3 From 47af00b2452ef7374cdda8769910799938d1303c Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 15 Apr 2026 09:19:26 -0400 Subject: zen: better error --- .../console/app/src/routes/zen/util/handler.ts | 25 +++++++++++----------- packages/console/core/src/model.ts | 1 + 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'packages/console/core/src/model.ts') diff --git a/packages/console/app/src/routes/zen/util/handler.ts b/packages/console/app/src/routes/zen/util/handler.ts index 46d843522..58df61809 100644 --- a/packages/console/app/src/routes/zen/util/handler.ts +++ b/packages/console/app/src/routes/zen/util/handler.ts @@ -222,22 +222,23 @@ export async function handler( logger.debug("STATUS: " + res.status + " " + res.statusText) // Handle non-streaming response - if (!isStream) { + if (!isStream || res.status === 429) { const json = await res.json() - const usageInfo = providerInfo.normalizeUsage(json.usage) - const costInfo = calculateCost(modelInfo, usageInfo) - await trialLimiter?.track(usageInfo) await rateLimiter?.track() - await trackUsage(sessionId, billingSource, authInfo, modelInfo, providerInfo, usageInfo, costInfo) - await reload(billingSource, authInfo, costInfo) + if (json.usage) { + const usageInfo = providerInfo.normalizeUsage(json.usage) + const costInfo = calculateCost(modelInfo, usageInfo) + await trialLimiter?.track(usageInfo) + await trackUsage(sessionId, billingSource, authInfo, modelInfo, providerInfo, usageInfo, costInfo) + await reload(billingSource, authInfo, costInfo) + json.cost = calculateOccurredCost(billingSource, costInfo) + } + if (json.error?.message) { + json.error.message = `Error from provider${providerInfo.displayName ? ` (${providerInfo.displayName})` : ""}: ${json.error.message}` + } const responseConverter = createResponseConverter(providerInfo.format, opts.format) - const body = JSON.stringify( - responseConverter({ - ...json, - cost: calculateOccurredCost(billingSource, costInfo), - }), - ) + const body = JSON.stringify(responseConverter(json)) logger.metric({ response_length: body.length }) logger.debug("RESPONSE: " + body) dataDumper?.provideResponse(body) diff --git a/packages/console/core/src/model.ts b/packages/console/core/src/model.ts index b4149373f..3d614d303 100644 --- a/packages/console/core/src/model.ts +++ b/packages/console/core/src/model.ts @@ -44,6 +44,7 @@ export namespace ZenData { }) const ProviderSchema = z.object({ + displayName: z.string().optional(), api: z.string(), apiKey: z.union([z.string(), z.record(z.string(), z.string())]), format: FormatSchema.optional(), -- cgit v1.2.3