feat: 增加Azure opanai 能力支持

This commit is contained in:
Duang Cheng 2023-04-19 19:45:37 +08:00
parent beb04d8181
commit 19949906c6
6 changed files with 89 additions and 9 deletions

View File

@ -1,15 +1,21 @@
import { NextRequest } from "next/server";
const OPENAI_URL = "api.openai.com";
const AZURE_OPENAI_URL = "azure-openai-gpt.openai.azure.com";
const DEFAULT_PROTOCOL = "https";
const PROTOCOL = process.env.PROTOCOL ?? DEFAULT_PROTOCOL;
const BASE_URL = process.env.BASE_URL ?? OPENAI_URL;
export async function requestOpenai(req: NextRequest) {
const apiKey = req.headers.get("token");
const openaiPath = req.headers.get("path");
let baseUrl = BASE_URL;
let baseUrl = OPENAI_URL;
if (openaiPath?.includes("/deployments/")) {
baseUrl = AZURE_OPENAI_URL;
}
if (process.env.BASE_URL) {
baseUrl = process.env.BASE_URL;
}
if (!baseUrl.startsWith("http")) {
baseUrl = `${PROTOCOL}://${baseUrl}`;
@ -22,6 +28,7 @@ export async function requestOpenai(req: NextRequest) {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
"api-key": apiKey || "",
},
method: req.method,
body: req.body,

View File

@ -23,6 +23,7 @@ import {
useUpdateStore,
useAccessStore,
ModalConfigValidator,
AZURE_API_VERSION,
} from "../store";
import { Avatar } from "./chat";
@ -466,6 +467,34 @@ export function Settings(props: { closeSettings: () => void }) {
<></>
)}
<SettingItem title={Locale.Settings.EnableAOAI}>
<input
type="checkbox"
checked={accessStore.enableAOAI}
onChange={(e) => {
accessStore.switchAOAI(e.currentTarget.checked);
}}
></input>
</SettingItem>
{accessStore.enableAOAI ? (
<SettingItem
title={Locale.Settings.AzureDeploymentName.Title}
subTitle={Locale.Settings.AzureDeploymentName.SubTitle}
>
<PasswordInput
value={accessStore.azureDeployName}
type="text"
placeholder={Locale.Settings.AzureDeploymentName.Placeholder}
onChange={(e) => {
accessStore.updateDeployName(e.currentTarget.value);
}}
/>
</SettingItem>
) : (
<></>
)}
<SettingItem
title={Locale.Settings.Token.Title}
subTitle={Locale.Settings.Token.SubTitle}
@ -588,11 +617,13 @@ export function Settings(props: { closeSettings: () => void }) {
);
}}
>
{ALL_MODELS.map((v) => (
{(accessStore.enableAOAI ? AZURE_API_VERSION : ALL_MODELS).map(
(v) => (
<option value={v.name} key={v.name} disabled={!v.available}>
{v.name}
</option>
))}
),
)}
</select>
</SettingItem>
<SettingItem

View File

@ -96,6 +96,7 @@ const cn = {
Theme: "主题",
TightBorder: "无边框模式",
SendPreviewBubble: "发送预览气泡",
Prompt: {
Disable: {
Title: "禁用提示词自动补全",
@ -124,6 +125,12 @@ const cn = {
SubTitle: "使用自己的 Key 可绕过密码访问限制",
Placeholder: "OpenAI API Key",
},
EnableAOAI: "使用 Azure OpenAI",
AzureDeploymentName: {
Title: "Azure OpenAI 部署实例名称",
SubTitle: "启用Azure OpenAI后, 输入部署的实例名称",
Placeholder: "实例名称",
},
Usage: {
Title: "余额查询",
SubTitle(used: any, total: any) {

View File

@ -48,6 +48,17 @@ function getHeaders() {
return headers;
}
function getRequestPath() {
const OPENAI_REQUEST_PATH = "v1/chat/completions";
const { enableAOAI, azureDeployName } = useAccessStore.getState();
const { modelConfig } = useChatStore.getState().config;
if (!enableAOAI) return OPENAI_REQUEST_PATH;
const AZURE_REQUEST_PATH = `openai/deployments/${azureDeployName}/chat/completions?api-version=${modelConfig.model}`;
return AZURE_REQUEST_PATH;
}
export function requestOpenaiClient(path: string) {
return (body: any, method = "POST") =>
fetch("/api/openai?_vercel_no_cache=1", {
@ -64,7 +75,7 @@ export function requestOpenaiClient(path: string) {
export async function requestChat(messages: Message[]) {
const req: ChatRequest = makeRequestParam(messages, { filterBot: true });
const res = await requestOpenaiClient("v1/chat/completions")(req);
const res = await requestOpenaiClient(getRequestPath())(req);
try {
const response = (await res.json()) as ChatResponse;
@ -149,7 +160,7 @@ export async function requestChatStream(
method: "POST",
headers: {
"Content-Type": "application/json",
path: "v1/chat/completions",
path: getRequestPath(),
...getHeaders(),
},
body: JSON.stringify(req),

View File

@ -5,10 +5,15 @@ export interface AccessControlStore {
accessCode: string;
token: string;
enableAOAI: boolean;
azureDeployName: string;
needCode: boolean;
updateToken: (_: string) => void;
updateCode: (_: string) => void;
updateDeployName: (_: string) => void;
switchAOAI: (_: boolean) => void;
enabledAccessControl: () => boolean;
isAuthorized: () => boolean;
fetch: () => void;
@ -23,6 +28,8 @@ export const useAccessStore = create<AccessControlStore>()(
(set, get) => ({
token: "",
accessCode: "",
azureDeployName: "",
enableAOAI: false,
needCode: true,
enabledAccessControl() {
get().fetch();
@ -35,8 +42,18 @@ export const useAccessStore = create<AccessControlStore>()(
updateToken(token: string) {
set((state) => ({ token }));
},
updateDeployName(azureDeployName: string) {
set((state) => ({ azureDeployName }));
},
switchAOAI(switchStatus: boolean) {
set((state) => ({ enableAOAI: switchStatus }));
},
isAuthorized() {
// has token or has code or disabled access control
if (get().enableAOAI) {
return !!get().azureDeployName && !!get().token;
}
return (
!!get().token || !!get().accessCode || !get().enabledAccessControl()
);

View File

@ -71,6 +71,13 @@ export const ROLES: Message["role"][] = ["system", "user", "assistant"];
const ENABLE_GPT4 = true;
export const AZURE_API_VERSION = [
{
name: "2023-03-15-preview",
available: true,
},
];
export const ALL_MODELS = [
{
name: "gpt-4",