diff --git a/packages/console/app/src/routes/zen/util/handler.ts b/packages/console/app/src/routes/zen/util/handler.ts index 3446307bd..8895cdcf1 100644 --- a/packages/console/app/src/routes/zen/util/handler.ts +++ b/packages/console/app/src/routes/zen/util/handler.ts @@ -97,8 +97,8 @@ export async function handler( const zenData = ZenData.list(opts.modelList) const modelInfo = validateModel(zenData, model) const dataDumper = createDataDumper(sessionId, requestId, projectId) - const trialLimiter = createTrialLimiter(modelInfo.trialProvider, ip) - const trialProvider = await trialLimiter?.check() + const trialLimiter = createTrialLimiter(modelInfo.trialProviders, ip) + const trialProviders = await trialLimiter?.check() const rateLimiter = createRateLimiter( modelInfo.id, modelInfo.allowAnonymous, @@ -120,7 +120,7 @@ export async function handler( authInfo, modelInfo, sessionId, - trialProvider, + trialProviders, retry, stickyProvider, ) @@ -402,7 +402,7 @@ export async function handler( authInfo: AuthInfo, modelInfo: ModelInfo, sessionId: string, - trialProvider: string | undefined, + trialProviders: string[] | undefined, retry: RetryOptions, stickyProvider: string | undefined, ) { @@ -411,15 +411,17 @@ export async function handler( return modelInfo.providers.find((provider) => provider.id === modelInfo.byokProvider) } - if (trialProvider) { - return modelInfo.providers.find((provider) => provider.id === trialProvider) - } - if (stickyProvider) { const provider = modelInfo.providers.find((provider) => provider.id === stickyProvider) if (provider) return provider } + if (trialProviders) { + const trialProvider = trialProviders[Math.floor(Math.random() * trialProviders.length)] + const provider = modelInfo.providers.find((provider) => provider.id === trialProvider) + if (provider) return provider + } + if (retry.retryCount !== MAX_FAILOVER_RETRIES) { const providers = modelInfo.providers .filter((provider) => !provider.disabled) diff --git a/packages/console/app/src/routes/zen/util/provider/anthropic.ts b/packages/console/app/src/routes/zen/util/provider/anthropic.ts index 95c50fbdb..15fe75b84 100644 --- a/packages/console/app/src/routes/zen/util/provider/anthropic.ts +++ b/packages/console/app/src/routes/zen/util/provider/anthropic.ts @@ -175,7 +175,8 @@ export const anthropicHelper: ProviderHelper = ({ reqModel, providerModel }) => outputTokens: usage.output_tokens ?? 0, reasoningTokens: undefined, cacheReadTokens: usage.cache_read_input_tokens ?? undefined, - cacheWrite5mTokens: usage.cache_creation?.ephemeral_5m_input_tokens ?? undefined, + cacheWrite5mTokens: + usage.cache_creation?.ephemeral_5m_input_tokens ?? usage.cache_creation_input_tokens ?? undefined, cacheWrite1hTokens: usage.cache_creation?.ephemeral_1h_input_tokens ?? undefined, }), } diff --git a/packages/console/app/src/routes/zen/util/trialLimiter.ts b/packages/console/app/src/routes/zen/util/trialLimiter.ts index 1ae0ab329..319825dd7 100644 --- a/packages/console/app/src/routes/zen/util/trialLimiter.ts +++ b/packages/console/app/src/routes/zen/util/trialLimiter.ts @@ -3,8 +3,8 @@ import { IpTable } from "@opencode-ai/console-core/schema/ip.sql.js" import { UsageInfo } from "./provider/provider" import { Subscription } from "@opencode-ai/console-core/subscription.js" -export function createTrialLimiter(trialProvider: string | undefined, ip: string) { - if (!trialProvider) return +export function createTrialLimiter(trialProviders: string[] | undefined, ip: string) { + if (!trialProviders) return if (!ip) return const limit = Subscription.getFreeLimits().promoTokens @@ -24,7 +24,7 @@ export function createTrialLimiter(trialProvider: string | undefined, ip: string ) _isTrial = (data?.usage ?? 0) < limit - return _isTrial ? trialProvider : undefined + return _isTrial ? trialProviders : undefined }, track: async (usageInfo: UsageInfo) => { if (!_isTrial) return diff --git a/packages/console/core/src/model.ts b/packages/console/core/src/model.ts index f859f0d3c..c47e4a6d8 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(), - trialProvider: z.string().optional(), + trialProviders: z.array(z.string()).optional(), fallbackProvider: z.string().optional(), rateLimit: z.number().optional(), providers: z.array(