mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-10-01 23:56:39 +08:00
Merge remote-tracking branch 'upstream/main'
# Conflicts: # app/api/common.ts
This commit is contained in:
commit
e6912f5be8
@ -63,7 +63,7 @@ dist
|
|||||||
|
|
||||||
# Gatsby files
|
# Gatsby files
|
||||||
.cache/
|
.cache/
|
||||||
public
|
|
||||||
|
|
||||||
# Vuepress build output
|
# Vuepress build output
|
||||||
.vuepress/dist
|
.vuepress/dist
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# Your openai api key. (required)
|
# Your openai api key. (required)
|
||||||
OPENAI_API_KEY=sk-xxxx
|
OPENAI_API_KEY=sk-xxxx
|
||||||
|
|
||||||
# Access passsword, separated by comma. (optional)
|
# Access password, separated by comma. (optional)
|
||||||
CODE=your-password
|
CODE=your-password
|
||||||
|
|
||||||
# You can start service behind a proxy
|
# You can start service behind a proxy
|
||||||
|
@ -51,10 +51,6 @@ export async function requestOpenai(
|
|||||||
|
|
||||||
// console.log("[Proxy] ", path);
|
// console.log("[Proxy] ", path);
|
||||||
// console.log("[Base Url]", baseUrl);
|
// console.log("[Base Url]", baseUrl);
|
||||||
// // this fix [Org ID] undefined in server side if not using custom point
|
|
||||||
// if (serverConfig.openaiOrgId !== undefined) {
|
|
||||||
// console.log("[Org ID]", serverConfig.openaiOrgId);
|
|
||||||
// }
|
|
||||||
|
|
||||||
const timeoutId = setTimeout(
|
const timeoutId = setTimeout(
|
||||||
() => {
|
() => {
|
||||||
@ -110,12 +106,29 @@ export async function requestOpenai(
|
|||||||
try {
|
try {
|
||||||
const res = await fetch(fetchUrl, fetchOptions);
|
const res = await fetch(fetchUrl, fetchOptions);
|
||||||
|
|
||||||
|
// Extract the OpenAI-Organization header from the response
|
||||||
|
const openaiOrganizationHeader = res.headers.get("OpenAI-Organization");
|
||||||
|
|
||||||
|
// Check if serverConfig.openaiOrgId is defined and not an empty string
|
||||||
|
if (serverConfig.openaiOrgId && serverConfig.openaiOrgId.trim() !== "") {
|
||||||
|
// If openaiOrganizationHeader is present, log it; otherwise, log that the header is not present
|
||||||
|
console.log("[Org ID]", openaiOrganizationHeader);
|
||||||
|
} else {
|
||||||
|
console.log("[Org ID] is not set up.");
|
||||||
|
}
|
||||||
|
|
||||||
// to prevent browser prompt for credentials
|
// to prevent browser prompt for credentials
|
||||||
const newHeaders = new Headers(res.headers);
|
const newHeaders = new Headers(res.headers);
|
||||||
newHeaders.delete("www-authenticate");
|
newHeaders.delete("www-authenticate");
|
||||||
// to disable nginx buffering
|
// to disable nginx buffering
|
||||||
newHeaders.set("X-Accel-Buffering", "no");
|
newHeaders.set("X-Accel-Buffering", "no");
|
||||||
|
|
||||||
|
// Conditionally delete the OpenAI-Organization header from the response if [Org ID] is undefined or empty (not setup in ENV)
|
||||||
|
// Also, this is to prevent the header from being sent to the client
|
||||||
|
if (!serverConfig.openaiOrgId || serverConfig.openaiOrgId.trim() === "") {
|
||||||
|
newHeaders.delete("OpenAI-Organization");
|
||||||
|
}
|
||||||
|
|
||||||
// The latest version of the OpenAI API forced the content-encoding to be "br" in json response
|
// The latest version of the OpenAI API forced the content-encoding to be "br" in json response
|
||||||
// So if the streaming is disabled, we need to remove the content-encoding header
|
// So if the streaming is disabled, we need to remove the content-encoding header
|
||||||
// Because Vercel uses gzip to compress the response, if we don't remove the content-encoding header
|
// Because Vercel uses gzip to compress the response, if we don't remove the content-encoding header
|
||||||
|
@ -239,19 +239,31 @@ export class ChatGPTApi implements LLMApi {
|
|||||||
}
|
}
|
||||||
const text = msg.data;
|
const text = msg.data;
|
||||||
try {
|
try {
|
||||||
const json = JSON.parse(text) as {
|
const json = JSON.parse(text);
|
||||||
choices: Array<{
|
const choices = json.choices as Array<{
|
||||||
delta: {
|
delta: { content: string };
|
||||||
content: string;
|
|
||||||
};
|
|
||||||
}>;
|
}>;
|
||||||
};
|
const delta = choices[0]?.delta?.content;
|
||||||
const delta = json.choices[0]?.delta?.content;
|
const textmoderation = json?.prompt_filter_results;
|
||||||
|
|
||||||
if (delta) {
|
if (delta) {
|
||||||
remainText += delta;
|
remainText += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
textmoderation &&
|
||||||
|
textmoderation.length > 0 &&
|
||||||
|
ServiceProvider.Azure
|
||||||
|
) {
|
||||||
|
const contentFilterResults =
|
||||||
|
textmoderation[0]?.content_filter_results;
|
||||||
|
console.log(
|
||||||
|
`[${ServiceProvider.Azure}] [Text Moderation] flagged categories result:`,
|
||||||
|
contentFilterResults,
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("[Request] parse error", text);
|
console.error("[Request] parse error", text, msg);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onclose() {
|
onclose() {
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
import { useChatStore } from "../store";
|
import { useChatStore } from "../store";
|
||||||
|
|
||||||
import Locale from "../locales";
|
import Locale from "../locales";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||||
import { Path } from "../constant";
|
import { Path } from "../constant";
|
||||||
import { MaskAvatar } from "./mask";
|
import { MaskAvatar } from "./mask";
|
||||||
import { Mask } from "../store/mask";
|
import { Mask } from "../store/mask";
|
||||||
@ -40,12 +40,16 @@ export function ChatItem(props: {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [props.selected]);
|
}, [props.selected]);
|
||||||
|
|
||||||
|
const { pathname: currentPath } = useLocation();
|
||||||
return (
|
return (
|
||||||
<Draggable draggableId={`${props.id}`} index={props.index}>
|
<Draggable draggableId={`${props.id}`} index={props.index}>
|
||||||
{(provided) => (
|
{(provided) => (
|
||||||
<div
|
<div
|
||||||
className={`${styles["chat-item"]} ${
|
className={`${styles["chat-item"]} ${
|
||||||
props.selected && styles["chat-item-selected"]
|
props.selected &&
|
||||||
|
(currentPath === Path.Chat || currentPath === Path.Home) &&
|
||||||
|
styles["chat-item-selected"]
|
||||||
}`}
|
}`}
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
ref={(ele) => {
|
ref={(ele) => {
|
||||||
|
@ -404,7 +404,16 @@ export function MaskPage() {
|
|||||||
const maskStore = useMaskStore();
|
const maskStore = useMaskStore();
|
||||||
const chatStore = useChatStore();
|
const chatStore = useChatStore();
|
||||||
|
|
||||||
const [filterLang, setFilterLang] = useState<Lang>();
|
const [filterLang, setFilterLang] = useState<Lang | undefined>(
|
||||||
|
localStorage.getItem("Mask-language") as Lang | undefined,
|
||||||
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
if (filterLang) {
|
||||||
|
localStorage.setItem("Mask-language", filterLang);
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem("Mask-language");
|
||||||
|
}
|
||||||
|
}, [filterLang]);
|
||||||
|
|
||||||
const allMasks = maskStore
|
const allMasks = maskStore
|
||||||
.getAll()
|
.getAll()
|
||||||
|
@ -227,7 +227,7 @@ export function MessageSelector(props: {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles["checkbox"]}>
|
<div className={styles["checkbox"]}>
|
||||||
<input type="checkbox" checked={isSelected}></input>
|
<input type="checkbox" checked={isSelected} readOnly></input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -865,6 +865,7 @@ export const useChatStore = createPersistStore(
|
|||||||
messages: topicMessages,
|
messages: topicMessages,
|
||||||
config: {
|
config: {
|
||||||
model: getSummarizeModel(session.mask.modelConfig.model),
|
model: getSummarizeModel(session.mask.modelConfig.model),
|
||||||
|
stream: false,
|
||||||
},
|
},
|
||||||
onFinish(message) {
|
onFinish(message) {
|
||||||
get().updateCurrentSession(
|
get().updateCurrentSession(
|
||||||
@ -908,6 +909,10 @@ export const useChatStore = createPersistStore(
|
|||||||
historyMsgLength > modelConfig.compressMessageLengthThreshold &&
|
historyMsgLength > modelConfig.compressMessageLengthThreshold &&
|
||||||
modelConfig.sendMemory
|
modelConfig.sendMemory
|
||||||
) {
|
) {
|
||||||
|
/** Destruct max_tokens while summarizing
|
||||||
|
* this param is just shit
|
||||||
|
**/
|
||||||
|
const { max_tokens, ...modelcfg } = modelConfig;
|
||||||
api.llm.chat({
|
api.llm.chat({
|
||||||
messages: toBeSummarizedMsgs.concat(
|
messages: toBeSummarizedMsgs.concat(
|
||||||
createMessage({
|
createMessage({
|
||||||
@ -917,7 +922,7 @@ export const useChatStore = createPersistStore(
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
config: {
|
config: {
|
||||||
...modelConfig,
|
...modelcfg,
|
||||||
stream: true,
|
stream: true,
|
||||||
model: getSummarizeModel(session.mask.modelConfig.model),
|
model: getSummarizeModel(session.mask.modelConfig.model),
|
||||||
},
|
},
|
||||||
|
@ -18,8 +18,15 @@ export function createWebDavClient(store: SyncStore) {
|
|||||||
method: "MKCOL",
|
method: "MKCOL",
|
||||||
headers: this.headers(),
|
headers: this.headers(),
|
||||||
});
|
});
|
||||||
console.log("[WebDav] check", res.status, res.statusText);
|
const success = [201, 200, 404, 405, 301, 302, 307, 308].includes(
|
||||||
return [201, 200, 404, 301, 302, 307, 308].includes(res.status);
|
res.status,
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
`[WebDav] check ${success ? "success" : "failed"}, ${res.status} ${
|
||||||
|
res.statusText
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
return success;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("[WebDav] failed to check", e);
|
console.error("[WebDav] failed to check", e);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user