mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-09 11:36:38 +08:00
feat: 增加Azure opanai 能力支持
This commit is contained in:
parent
beb04d8181
commit
19949906c6
@ -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,
|
||||
|
@ -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) => (
|
||||
<option value={v.name} key={v.name} disabled={!v.available}>
|
||||
{v.name}
|
||||
</option>
|
||||
))}
|
||||
{(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
|
||||
|
@ -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) {
|
||||
|
@ -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),
|
||||
|
@ -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()
|
||||
);
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user