From 31ffda275e197278e8a0bd2d9a12c7c820895fbb Mon Sep 17 00:00:00 2001 From: nanaya Date: Sun, 12 Nov 2023 10:06:35 +0800 Subject: [PATCH 1/2] feat: leverage `CUSTOM_MODELS` to support azure deployment selection use `-` to hide all internal models and use `+` to add azure deployments. with the latest rename feat, a meaningful display name can be set by `{deployment-id}:{model-display-name}` --- app/api/common.ts | 69 ++++++++++++++++++++++++----------------------- app/azure.ts | 13 +++++++++ 2 files changed, 49 insertions(+), 33 deletions(-) diff --git a/app/api/common.ts b/app/api/common.ts index dd1cc0bb80e..b3fd8e463e9 100644 --- a/app/api/common.ts +++ b/app/api/common.ts @@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from "next/server"; import { getServerSideConfig } from "../config/server"; import { DEFAULT_MODELS, OPENAI_BASE_URL } from "../constant"; import { collectModelTable } from "../utils/model"; -import { makeAzurePath } from "../azure"; +import { makeAzurePath, makeAzureBaseUrl } from "../azure"; const serverConfig = getServerSideConfig(); @@ -17,8 +17,40 @@ export async function requestOpenai(req: NextRequest) { "", ); - let baseUrl = - serverConfig.azureUrl || serverConfig.baseUrl || OPENAI_BASE_URL; + let requestBody: ReadableStream | string | null = req.body; + let azureUrl = serverConfig.azureUrl; + if (serverConfig.customModels && requestBody) { + try { + const modelTable = collectModelTable( + DEFAULT_MODELS, + serverConfig.customModels, + ); + const clonedBody = await req.text(); + requestBody = clonedBody; + const jsonBody = JSON.parse(clonedBody) as { model?: string }; + + const model = modelTable[jsonBody?.model ?? ""]; + if (azureUrl && model.available === true) { + azureUrl = makeAzureBaseUrl(azureUrl, model.name); + } else if (model.available === false) { + // not undefined and is false + // #1815 try to refuse gpt4 request + return NextResponse.json( + { + error: true, + message: `you are not allowed to use ${jsonBody?.model} model`, + }, + { + status: 403, + }, + ); + } + } catch (e) { + console.error("[OpenAI] gpt4 filter", e); + } + } + + let baseUrl = azureUrl || serverConfig.baseUrl || OPENAI_BASE_URL; if (!baseUrl.startsWith("http")) { baseUrl = `https://${baseUrl}`; @@ -60,7 +92,7 @@ export async function requestOpenai(req: NextRequest) { }), }, method: req.method, - body: req.body, + body: requestBody, // to fix #2485: https://stackoverflow.com/questions/55920957/cloudflare-worker-typeerror-one-time-use-body redirect: "manual", // @ts-ignore @@ -68,35 +100,6 @@ export async function requestOpenai(req: NextRequest) { signal: controller.signal, }; - // #1815 try to refuse gpt4 request - if (serverConfig.customModels && req.body) { - try { - const modelTable = collectModelTable( - DEFAULT_MODELS, - serverConfig.customModels, - ); - const clonedBody = await req.text(); - fetchOptions.body = clonedBody; - - const jsonBody = JSON.parse(clonedBody) as { model?: string }; - - // not undefined and is false - if (modelTable[jsonBody?.model ?? ""].available === false) { - return NextResponse.json( - { - error: true, - message: `you are not allowed to use ${jsonBody?.model} model`, - }, - { - status: 403, - }, - ); - } - } catch (e) { - console.error("[OpenAI] gpt4 filter", e); - } - } - try { const res = await fetch(fetchUrl, fetchOptions); diff --git a/app/azure.ts b/app/azure.ts index 48406c55ba5..774cfaa90a4 100644 --- a/app/azure.ts +++ b/app/azure.ts @@ -7,3 +7,16 @@ export function makeAzurePath(path: string, apiVersion: string) { return path; } + +export function makeAzureBaseUrl( + url: string, + deploymentId: string | undefined, +) { + const DEPLOYMENTS = "deployments"; + if (!deploymentId || url.indexOf(DEPLOYMENTS) == -1) { + return url; + } + + const end = url.indexOf(DEPLOYMENTS) + DEPLOYMENTS.length; + return url.substring(0, end) + "/" + deploymentId; +} From 13691a4dbc5a05d9d0d3c73826003cf7a5527092 Mon Sep 17 00:00:00 2001 From: nanaya Date: Sun, 12 Nov 2023 14:52:36 +0800 Subject: [PATCH 2/2] fix: don't send model unavailable response when using Azure openAI --- app/api/common.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/api/common.ts b/app/api/common.ts index b3fd8e463e9..e0008d106b6 100644 --- a/app/api/common.ts +++ b/app/api/common.ts @@ -30,9 +30,7 @@ export async function requestOpenai(req: NextRequest) { const jsonBody = JSON.parse(clonedBody) as { model?: string }; const model = modelTable[jsonBody?.model ?? ""]; - if (azureUrl && model.available === true) { - azureUrl = makeAzureBaseUrl(azureUrl, model.name); - } else if (model.available === false) { + if (!azureUrl && model.available === false) { // not undefined and is false // #1815 try to refuse gpt4 request return NextResponse.json( @@ -44,6 +42,10 @@ export async function requestOpenai(req: NextRequest) { status: 403, }, ); + } else if (azureUrl && model.available === true) { + // if there is an avaliable model, update the deployment id in the url. + // otherwise leave the url unchanged. + azureUrl = makeAzureBaseUrl(azureUrl, model.name); } } catch (e) { console.error("[OpenAI] gpt4 filter", e);