Skip to content

Commit 6667ee1

Browse files
committed
merge main
2 parents 3086a2f + 6ded4e9 commit 6667ee1

File tree

11 files changed

+155
-73
lines changed

11 files changed

+155
-73
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,14 @@ iflytek Api Key.
301301

302302
iflytek Api Secret.
303303

304+
### `CHATGLM_API_KEY` (optional)
305+
306+
ChatGLM Api Key.
307+
308+
### `CHATGLM_URL` (optional)
309+
310+
ChatGLM Api Url.
311+
304312
### `HIDE_USER_API_KEY` (optional)
305313

306314
> Default: Empty

README_CN.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ ByteDance Api Url.
184184

185185
讯飞星火Api Secret.
186186

187+
### `CHATGLM_API_KEY` (可选)
188+
189+
ChatGLM Api Key.
190+
191+
### `CHATGLM_URL` (可选)
192+
193+
ChatGLM Api Url.
187194

188195

189196
### `HIDE_USER_API_KEY` (可选)

app/api/common.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { NextRequest, NextResponse } from "next/server";
22
import { getServerSideConfig } from "../config/server";
33
import { OPENAI_BASE_URL, ServiceProvider } from "../constant";
4-
import { isModelAvailableInServer } from "../utils/model";
54
import { cloudflareAIGatewayUrl } from "../utils/cloudflare";
5+
import { getModelProvider, isModelAvailableInServer } from "../utils/model";
66

77
const serverConfig = getServerSideConfig();
88

@@ -71,7 +71,7 @@ export async function requestOpenai(req: NextRequest) {
7171
.filter((v) => !!v && !v.startsWith("-") && v.includes(modelName))
7272
.forEach((m) => {
7373
const [fullName, displayName] = m.split("=");
74-
const [_, providerName] = fullName.split("@");
74+
const [_, providerName] = getModelProvider(fullName);
7575
if (providerName === "azure" && !displayName) {
7676
const [_, deployId] = (serverConfig?.azureUrl ?? "").split(
7777
"deployments/",

app/components/chat.tsx

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ import { createTTSPlayer } from "../utils/audio";
120120
import { MsEdgeTTS, OUTPUT_FORMAT } from "../utils/ms_edge_tts";
121121

122122
import { isEmpty } from "lodash-es";
123+
import { getModelProvider } from "../utils/model";
123124

124125
const localStorage = safeLocalStorage();
125126

@@ -148,7 +149,8 @@ export function SessionConfigModel(props: { onClose: () => void }) {
148149
text={Locale.Chat.Config.Reset}
149150
onClick={async () => {
150151
if (await showConfirm(Locale.Memory.ResetConfirm)) {
151-
chatStore.updateCurrentSession(
152+
chatStore.updateTargetSession(
153+
session,
152154
(session) => (session.memoryPrompt = ""),
153155
);
154156
}
@@ -173,7 +175,10 @@ export function SessionConfigModel(props: { onClose: () => void }) {
173175
updateMask={(updater) => {
174176
const mask = { ...session.mask };
175177
updater(mask);
176-
chatStore.updateCurrentSession((session) => (session.mask = mask));
178+
chatStore.updateTargetSession(
179+
session,
180+
(session) => (session.mask = mask),
181+
);
177182
}}
178183
shouldSyncFromGlobal
179184
extraListItems={
@@ -345,12 +350,14 @@ export function PromptHints(props: {
345350

346351
function ClearContextDivider() {
347352
const chatStore = useChatStore();
353+
const session = chatStore.currentSession();
348354

349355
return (
350356
<div
351357
className={styles["clear-context"]}
352358
onClick={() =>
353-
chatStore.updateCurrentSession(
359+
chatStore.updateTargetSession(
360+
session,
354361
(session) => (session.clearContextIndex = undefined),
355362
)
356363
}
@@ -460,6 +467,7 @@ export function ChatActions(props: {
460467
const navigate = useNavigate();
461468
const chatStore = useChatStore();
462469
const pluginStore = usePluginStore();
470+
const session = chatStore.currentSession();
463471

464472
// switch themes
465473
const theme = config.theme;
@@ -476,10 +484,9 @@ export function ChatActions(props: {
476484
const stopAll = () => ChatControllerPool.stopAll();
477485

478486
// switch model
479-
const currentModel = chatStore.currentSession().mask.modelConfig.model;
487+
const currentModel = session.mask.modelConfig.model;
480488
const currentProviderName =
481-
chatStore.currentSession().mask.modelConfig?.providerName ||
482-
ServiceProvider.OpenAI;
489+
session.mask.modelConfig?.providerName || ServiceProvider.OpenAI;
483490
const allModels = useAllModels();
484491
const models = useMemo(() => {
485492
const filteredModels = allModels.filter((m) => m.available);
@@ -513,12 +520,9 @@ export function ChatActions(props: {
513520
const dalle3Sizes: DalleSize[] = ["1024x1024", "1792x1024", "1024x1792"];
514521
const dalle3Qualitys: DalleQuality[] = ["standard", "hd"];
515522
const dalle3Styles: DalleStyle[] = ["vivid", "natural"];
516-
const currentSize =
517-
chatStore.currentSession().mask.modelConfig?.size ?? "1024x1024";
518-
const currentQuality =
519-
chatStore.currentSession().mask.modelConfig?.quality ?? "standard";
520-
const currentStyle =
521-
chatStore.currentSession().mask.modelConfig?.style ?? "vivid";
523+
const currentSize = session.mask.modelConfig?.size ?? "1024x1024";
524+
const currentQuality = session.mask.modelConfig?.quality ?? "standard";
525+
const currentStyle = session.mask.modelConfig?.style ?? "vivid";
522526

523527
const isMobileScreen = useMobileScreen();
524528

@@ -536,7 +540,7 @@ export function ChatActions(props: {
536540
if (isUnavailableModel && models.length > 0) {
537541
// show next model to default model if exist
538542
let nextModel = models.find((model) => model.isDefault) || models[0];
539-
chatStore.updateCurrentSession((session) => {
543+
chatStore.updateTargetSession(session, (session) => {
540544
session.mask.modelConfig.model = nextModel.name;
541545
session.mask.modelConfig.providerName = nextModel?.provider
542546
?.providerName as ServiceProvider;
@@ -547,7 +551,7 @@ export function ChatActions(props: {
547551
: nextModel.name,
548552
);
549553
}
550-
}, [chatStore, currentModel, models]);
554+
}, [chatStore, currentModel, models, session]);
551555

552556
return (
553557
<div className={styles["chat-input-actions"]}>
@@ -614,7 +618,7 @@ export function ChatActions(props: {
614618
text={Locale.Chat.InputActions.Clear}
615619
icon={<BreakIcon />}
616620
onClick={() => {
617-
chatStore.updateCurrentSession((session) => {
621+
chatStore.updateTargetSession(session, (session) => {
618622
if (session.clearContextIndex === session.messages.length) {
619623
session.clearContextIndex = undefined;
620624
} else {
@@ -645,8 +649,8 @@ export function ChatActions(props: {
645649
onClose={() => setShowModelSelector(false)}
646650
onSelection={(s) => {
647651
if (s.length === 0) return;
648-
const [model, providerName] = s[0].split("@");
649-
chatStore.updateCurrentSession((session) => {
652+
const [model, providerName] = getModelProvider(s[0]);
653+
chatStore.updateTargetSession(session, (session) => {
650654
session.mask.modelConfig.model = model as ModelType;
651655
session.mask.modelConfig.providerName =
652656
providerName as ServiceProvider;
@@ -684,7 +688,7 @@ export function ChatActions(props: {
684688
onSelection={(s) => {
685689
if (s.length === 0) return;
686690
const size = s[0];
687-
chatStore.updateCurrentSession((session) => {
691+
chatStore.updateTargetSession(session, (session) => {
688692
session.mask.modelConfig.size = size;
689693
});
690694
showToast(size);
@@ -711,7 +715,7 @@ export function ChatActions(props: {
711715
onSelection={(q) => {
712716
if (q.length === 0) return;
713717
const quality = q[0];
714-
chatStore.updateCurrentSession((session) => {
718+
chatStore.updateTargetSession(session, (session) => {
715719
session.mask.modelConfig.quality = quality;
716720
});
717721
showToast(quality);
@@ -738,7 +742,7 @@ export function ChatActions(props: {
738742
onSelection={(s) => {
739743
if (s.length === 0) return;
740744
const style = s[0];
741-
chatStore.updateCurrentSession((session) => {
745+
chatStore.updateTargetSession(session, (session) => {
742746
session.mask.modelConfig.style = style;
743747
});
744748
showToast(style);
@@ -769,7 +773,7 @@ export function ChatActions(props: {
769773
}))}
770774
onClose={() => setShowPluginSelector(false)}
771775
onSelection={(s) => {
772-
chatStore.updateCurrentSession((session) => {
776+
chatStore.updateTargetSession(session, (session) => {
773777
session.mask.plugin = s as string[];
774778
});
775779
}}
@@ -812,7 +816,8 @@ export function EditMessageModal(props: { onClose: () => void }) {
812816
icon={<ConfirmIcon />}
813817
key="ok"
814818
onClick={() => {
815-
chatStore.updateCurrentSession(
819+
chatStore.updateTargetSession(
820+
session,
816821
(session) => (session.messages = messages),
817822
);
818823
props.onClose();
@@ -829,7 +834,8 @@ export function EditMessageModal(props: { onClose: () => void }) {
829834
type="text"
830835
value={session.topic}
831836
onInput={(e) =>
832-
chatStore.updateCurrentSession(
837+
chatStore.updateTargetSession(
838+
session,
833839
(session) => (session.topic = e.currentTarget.value),
834840
)
835841
}
@@ -990,7 +996,8 @@ function _Chat() {
990996
prev: () => chatStore.nextSession(-1),
991997
next: () => chatStore.nextSession(1),
992998
clear: () =>
993-
chatStore.updateCurrentSession(
999+
chatStore.updateTargetSession(
1000+
session,
9941001
(session) => (session.clearContextIndex = session.messages.length),
9951002
),
9961003
fork: () => chatStore.forkSession(),
@@ -1061,7 +1068,7 @@ function _Chat() {
10611068
};
10621069

10631070
useEffect(() => {
1064-
chatStore.updateCurrentSession((session) => {
1071+
chatStore.updateTargetSession(session, (session) => {
10651072
const stopTiming = Date.now() - REQUEST_TIMEOUT_MS;
10661073
session.messages.forEach((m) => {
10671074
// check if should stop all stale messages
@@ -1087,7 +1094,7 @@ function _Chat() {
10871094
}
10881095
});
10891096
// eslint-disable-next-line react-hooks/exhaustive-deps
1090-
}, []);
1097+
}, [session]);
10911098

10921099
// check if should send message
10931100
const onInputKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
@@ -1118,7 +1125,8 @@ function _Chat() {
11181125
};
11191126

11201127
const deleteMessage = (msgId?: string) => {
1121-
chatStore.updateCurrentSession(
1128+
chatStore.updateTargetSession(
1129+
session,
11221130
(session) =>
11231131
(session.messages = session.messages.filter((m) => m.id !== msgId)),
11241132
);
@@ -1185,7 +1193,7 @@ function _Chat() {
11851193
};
11861194

11871195
const onPinMessage = (message: ChatMessage) => {
1188-
chatStore.updateCurrentSession((session) =>
1196+
chatStore.updateTargetSession(session, (session) =>
11891197
session.mask.context.push(message),
11901198
);
11911199

@@ -1607,7 +1615,7 @@ function _Chat() {
16071615
title={Locale.Chat.Actions.RefreshTitle}
16081616
onClick={() => {
16091617
showToast(Locale.Chat.Actions.RefreshToast);
1610-
chatStore.summarizeSession(true);
1618+
chatStore.summarizeSession(true, session);
16111619
}}
16121620
/>
16131621
</div>
@@ -1711,14 +1719,17 @@ function _Chat() {
17111719
});
17121720
}
17131721
}
1714-
chatStore.updateCurrentSession((session) => {
1715-
const m = session.mask.context
1716-
.concat(session.messages)
1717-
.find((m) => m.id === message.id);
1718-
if (m) {
1719-
m.content = newContent;
1720-
}
1721-
});
1722+
chatStore.updateTargetSession(
1723+
session,
1724+
(session) => {
1725+
const m = session.mask.context
1726+
.concat(session.messages)
1727+
.find((m) => m.id === message.id);
1728+
if (m) {
1729+
m.content = newContent;
1730+
}
1731+
},
1732+
);
17221733
}}
17231734
></IconButton>
17241735
</div>

app/components/model-config.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ListItem, Select } from "./ui-lib";
77
import { useAllModels } from "../utils/hooks";
88
import { groupBy } from "lodash-es";
99
import styles from "./model-config.module.scss";
10+
import { getModelProvider } from "../utils/model";
1011

1112
export function ModelConfigList(props: {
1213
modelConfig: ModelConfig;
@@ -28,7 +29,9 @@ export function ModelConfigList(props: {
2829
value={value}
2930
align="left"
3031
onChange={(e) => {
31-
const [model, providerName] = e.currentTarget.value.split("@");
32+
const [model, providerName] = getModelProvider(
33+
e.currentTarget.value,
34+
);
3235
props.updateConfig((config) => {
3336
config.model = ModalConfigValidator.model(model);
3437
config.providerName = providerName as ServiceProvider;
@@ -247,7 +250,9 @@ export function ModelConfigList(props: {
247250
aria-label={Locale.Settings.CompressModel.Title}
248251
value={compressModelValue}
249252
onChange={(e) => {
250-
const [model, providerName] = e.currentTarget.value.split("@");
253+
const [model, providerName] = getModelProvider(
254+
e.currentTarget.value,
255+
);
251256
props.updateConfig((config) => {
252257
config.compressModel = ModalConfigValidator.model(model);
253258
config.compressProviderName = providerName as ServiceProvider;

app/constant.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ export const XAI = {
232232

233233
export const ChatGLM = {
234234
ExampleEndpoint: CHATGLM_BASE_URL,
235-
ChatPath: "/api/paas/v4/chat/completions",
235+
ChatPath: "api/paas/v4/chat/completions",
236236
};
237237

238238
export const DEFAULT_INPUT_TEMPLATE = `{{input}}`; // input / time / model / lang
@@ -327,12 +327,13 @@ const anthropicModels = [
327327
"claude-2.1",
328328
"claude-3-sonnet-20240229",
329329
"claude-3-opus-20240229",
330+
"claude-3-opus-latest",
330331
"claude-3-haiku-20240307",
331332
"claude-3-5-haiku-20241022",
332333
"claude-3-5-sonnet-20240620",
333334
"claude-3-5-sonnet-20241022",
334335
"claude-3-5-sonnet-latest",
335-
"claude-3-opus-latest",
336+
"claude-3-5-haiku-latest",
336337
];
337338

338339
const baiduModels = [

app/store/access.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { getClientConfig } from "../config/client";
2121
import { createPersistStore } from "../utils/store";
2222
import { ensure } from "../utils/clone";
2323
import { DEFAULT_CONFIG } from "./config";
24+
import { getModelProvider } from "../utils/model";
2425

2526
let fetchState = 0; // 0 not fetch, 1 fetching, 2 done
2627

@@ -226,9 +227,9 @@ export const useAccessStore = createPersistStore(
226227
.then((res) => {
227228
const defaultModel = res.defaultModel ?? "";
228229
if (defaultModel !== "") {
229-
const [model, providerName] = defaultModel.split("@");
230+
const [model, providerName] = getModelProvider(defaultModel);
230231
DEFAULT_CONFIG.modelConfig.model = model;
231-
DEFAULT_CONFIG.modelConfig.providerName = providerName;
232+
DEFAULT_CONFIG.modelConfig.providerName = providerName as any;
232233
}
233234

234235
return res;

0 commit comments

Comments
 (0)