From 8ac860974ed111b30d6c24aedc98e34cddb788b6 Mon Sep 17 00:00:00 2001 From: Vaughn Date: Wed, 19 Nov 2025 01:55:48 +0000 Subject: [PATCH] feat: add Gatewayz provider support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for Gatewayz AI gateway as a provider in the Zen API system. Gatewayz uses OpenAI-compatible API format and integrates seamlessly with the existing provider infrastructure. 🤖 Generated with Claude Code Co-Authored-By: Claude --- .../src/routes/zen/util/provider/gatewayz.ts | 62 +++++++++++++++++++ .../src/routes/zen/util/provider/provider.ts | 1 + 2 files changed, 63 insertions(+) create mode 100644 packages/console/app/src/routes/zen/util/provider/gatewayz.ts diff --git a/packages/console/app/src/routes/zen/util/provider/gatewayz.ts b/packages/console/app/src/routes/zen/util/provider/gatewayz.ts new file mode 100644 index 00000000000..8b4e564e8cc --- /dev/null +++ b/packages/console/app/src/routes/zen/util/provider/gatewayz.ts @@ -0,0 +1,62 @@ +import { ProviderHelper, CommonRequest, CommonResponse, CommonChunk } from "./provider" + +type Usage = { + prompt_tokens?: number + completion_tokens?: number + total_tokens?: number + prompt_tokens_details?: { + cached_tokens?: number + } + completion_tokens_details?: { + reasoning_tokens?: number + } +} + +export const gatewayzHelper = { + format: "oa-compat", + modifyUrl: (providerApi: string) => providerApi + "/v1/chat/completions", + modifyHeaders: (headers: Headers, body: Record, apiKey: string) => { + headers.set("authorization", `Bearer ${apiKey}`) + }, + modifyBody: (body: Record) => { + return { + ...body, + ...(body.stream ? { stream_options: { include_usage: true } } : {}), + } + }, + streamSeparator: "\n\n", + createUsageParser: () => { + let usage: Usage + + return { + parse: (chunk: string) => { + if (!chunk.startsWith("data: ")) return + + let json + try { + json = JSON.parse(chunk.slice(6)) as { usage?: Usage } + } catch (e) { + return + } + + if (!json.usage) return + usage = json.usage + }, + retrieve: () => usage, + } + }, + normalizeUsage: (usage: Usage) => { + const inputTokens = usage.prompt_tokens ?? 0 + const outputTokens = usage.completion_tokens ?? 0 + const reasoningTokens = usage.completion_tokens_details?.reasoning_tokens ?? undefined + const cacheReadTokens = usage.prompt_tokens_details?.cached_tokens ?? undefined + return { + inputTokens: inputTokens - (cacheReadTokens ?? 0), + outputTokens, + reasoningTokens, + cacheReadTokens, + cacheWrite5mTokens: undefined, + cacheWrite1hTokens: undefined, + } + }, +} satisfies ProviderHelper diff --git a/packages/console/app/src/routes/zen/util/provider/provider.ts b/packages/console/app/src/routes/zen/util/provider/provider.ts index 8366f3a6388..62b77a06bbf 100644 --- a/packages/console/app/src/routes/zen/util/provider/provider.ts +++ b/packages/console/app/src/routes/zen/util/provider/provider.ts @@ -23,6 +23,7 @@ import { toOaCompatibleRequest, toOaCompatibleResponse, } from "./openai-compatible" +import { gatewayzHelper } from "./gatewayz" export type ProviderHelper = { format: ZenData.Format