@lobehub/chat 0.147.21 → 0.148.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/locales/ar/setting.json +4 -0
- package/locales/bg-BG/setting.json +4 -0
- package/locales/de-DE/setting.json +4 -0
- package/locales/en-US/setting.json +4 -0
- package/locales/es-ES/setting.json +4 -0
- package/locales/fr-FR/setting.json +4 -0
- package/locales/it-IT/setting.json +4 -0
- package/locales/ja-JP/setting.json +4 -0
- package/locales/ko-KR/setting.json +4 -0
- package/locales/nl-NL/setting.json +4 -0
- package/locales/pl-PL/setting.json +4 -0
- package/locales/pt-BR/setting.json +4 -0
- package/locales/ru-RU/setting.json +4 -0
- package/locales/tr-TR/setting.json +4 -0
- package/locales/vi-VN/setting.json +4 -0
- package/locales/zh-CN/setting.json +4 -0
- package/locales/zh-TW/setting.json +4 -0
- package/package.json +3 -2
- package/public/favicon-32x32.ico +0 -0
- package/public/favicon.ico +0 -0
- package/public/icons/apple-touch-icon.png +0 -0
- package/src/app/api/chat/[provider]/route.test.ts +5 -7
- package/src/app/api/chat/[provider]/route.ts +13 -7
- package/src/app/api/chat/agentRuntime.test.ts +195 -451
- package/src/app/api/chat/agentRuntime.ts +197 -280
- package/src/app/api/chat/models/[provider]/route.ts +2 -2
- package/src/app/chat/features/TopicListContent/Topic/TopicContent.tsx +2 -2
- package/src/app/metadata.ts +3 -5
- package/src/app/settings/llm/components/ProviderConfig/index.tsx +23 -1
- package/src/app/settings/llm/index.tsx +2 -2
- package/src/app/settings/llm/page.tsx +1 -5
- package/src/features/ChatInput/Topic/index.tsx +6 -2
- package/src/features/Conversation/components/ChatItem/index.tsx +8 -3
- package/src/libs/agent-runtime/AgentRuntime.test.ts +400 -0
- package/src/libs/agent-runtime/AgentRuntime.ts +192 -0
- package/src/libs/agent-runtime/index.ts +1 -0
- package/src/libs/swr/index.ts +9 -0
- package/src/locales/default/setting.ts +4 -0
- package/src/services/__tests__/chat.test.ts +287 -1
- package/src/services/chat.ts +148 -2
- package/src/store/chat/slices/message/action.ts +80 -42
- package/src/store/chat/slices/message/initialState.ts +1 -1
- package/src/store/chat/slices/message/reducer.ts +32 -1
- package/src/store/chat/slices/topic/action.test.ts +25 -2
- package/src/store/chat/slices/topic/action.ts +24 -7
- package/src/store/chat/slices/topic/reducer.test.ts +141 -0
- package/src/store/chat/slices/topic/reducer.ts +67 -0
- package/src/store/global/slices/settings/selectors/modelConfig.ts +13 -0
- package/src/store/session/slices/session/action.ts +4 -5
- package/src/types/settings/modelProvider.ts +4 -0
- package/vercel.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import isEqual from 'fast-deep-equal';
|
|
2
2
|
import { produce } from 'immer';
|
|
3
3
|
|
|
4
|
+
import { CreateMessageParams } from '@/services/message';
|
|
4
5
|
import { ChatMessage } from '@/types/message';
|
|
5
6
|
import { merge } from '@/utils/merge';
|
|
6
7
|
|
|
@@ -10,6 +11,15 @@ interface UpdateMessage {
|
|
|
10
11
|
type: 'updateMessage';
|
|
11
12
|
value: ChatMessage[keyof ChatMessage];
|
|
12
13
|
}
|
|
14
|
+
interface CreateMessage {
|
|
15
|
+
id: string;
|
|
16
|
+
type: 'createMessage';
|
|
17
|
+
value: CreateMessageParams;
|
|
18
|
+
}
|
|
19
|
+
interface DeleteMessage {
|
|
20
|
+
id: string;
|
|
21
|
+
type: 'deleteMessage';
|
|
22
|
+
}
|
|
13
23
|
|
|
14
24
|
interface UpdatePluginState {
|
|
15
25
|
id: string;
|
|
@@ -24,7 +34,12 @@ interface UpdateMessageExtra {
|
|
|
24
34
|
value: any;
|
|
25
35
|
}
|
|
26
36
|
|
|
27
|
-
export type MessageDispatch =
|
|
37
|
+
export type MessageDispatch =
|
|
38
|
+
| CreateMessage
|
|
39
|
+
| UpdateMessage
|
|
40
|
+
| UpdatePluginState
|
|
41
|
+
| UpdateMessageExtra
|
|
42
|
+
| DeleteMessage;
|
|
28
43
|
|
|
29
44
|
export const messagesReducer = (state: ChatMessage[], payload: MessageDispatch): ChatMessage[] => {
|
|
30
45
|
switch (payload.type) {
|
|
@@ -76,6 +91,22 @@ export const messagesReducer = (state: ChatMessage[], payload: MessageDispatch):
|
|
|
76
91
|
});
|
|
77
92
|
}
|
|
78
93
|
|
|
94
|
+
case 'createMessage': {
|
|
95
|
+
return produce(state, (draftState) => {
|
|
96
|
+
const { value, id } = payload;
|
|
97
|
+
|
|
98
|
+
draftState.push({ ...value, createdAt: Date.now(), id, meta: {}, updatedAt: Date.now() });
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
case 'deleteMessage': {
|
|
102
|
+
return produce(state, (draft) => {
|
|
103
|
+
const { id } = payload;
|
|
104
|
+
|
|
105
|
+
const index = draft.findIndex((m) => m.id === id);
|
|
106
|
+
|
|
107
|
+
if (index >= 0) draft.splice(index, 1);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
79
110
|
default: {
|
|
80
111
|
throw new Error('暂未实现的 type,请检查 reducer');
|
|
81
112
|
}
|
|
@@ -149,7 +149,9 @@ describe('topic action', () => {
|
|
|
149
149
|
});
|
|
150
150
|
|
|
151
151
|
// Check if mutate has been called with the active session ID
|
|
152
|
-
expect(mutate).toHaveBeenCalledWith(['SWR_USE_FETCH_TOPIC', activeId]
|
|
152
|
+
expect(mutate).toHaveBeenCalledWith(['SWR_USE_FETCH_TOPIC', activeId], undefined, {
|
|
153
|
+
populateCache: false,
|
|
154
|
+
});
|
|
153
155
|
});
|
|
154
156
|
|
|
155
157
|
it('should handle errors during refreshing topics', async () => {
|
|
@@ -314,7 +316,7 @@ describe('topic action', () => {
|
|
|
314
316
|
const activeId = 'test-session-id';
|
|
315
317
|
|
|
316
318
|
await act(async () => {
|
|
317
|
-
useChatStore.setState({ activeId });
|
|
319
|
+
useChatStore.setState({ activeId, activeTopicId: topicId });
|
|
318
320
|
});
|
|
319
321
|
|
|
320
322
|
const refreshTopicSpy = vi.spyOn(result.current, 'refreshTopic');
|
|
@@ -329,6 +331,27 @@ describe('topic action', () => {
|
|
|
329
331
|
expect(refreshTopicSpy).toHaveBeenCalled();
|
|
330
332
|
expect(switchTopicSpy).toHaveBeenCalled();
|
|
331
333
|
});
|
|
334
|
+
it('should remove a specific topic and its messages, then not refresh the topic list', async () => {
|
|
335
|
+
const topicId = 'topic-1';
|
|
336
|
+
const { result } = renderHook(() => useChatStore());
|
|
337
|
+
const activeId = 'test-session-id';
|
|
338
|
+
|
|
339
|
+
await act(async () => {
|
|
340
|
+
useChatStore.setState({ activeId });
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
const refreshTopicSpy = vi.spyOn(result.current, 'refreshTopic');
|
|
344
|
+
const switchTopicSpy = vi.spyOn(result.current, 'switchTopic');
|
|
345
|
+
|
|
346
|
+
await act(async () => {
|
|
347
|
+
await result.current.removeTopic(topicId);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
expect(messageService.removeMessages).toHaveBeenCalledWith(activeId, topicId);
|
|
351
|
+
expect(topicService.removeTopic).toHaveBeenCalledWith(topicId);
|
|
352
|
+
expect(refreshTopicSpy).toHaveBeenCalled();
|
|
353
|
+
expect(switchTopicSpy).not.toHaveBeenCalled();
|
|
354
|
+
});
|
|
332
355
|
});
|
|
333
356
|
describe('removeUnstarredTopic', () => {
|
|
334
357
|
it('should remove unstarred topics and refresh the topic list', async () => {
|
|
@@ -9,11 +9,11 @@ import { StateCreator } from 'zustand/vanilla';
|
|
|
9
9
|
import { chainSummaryTitle } from '@/chains/summaryTitle';
|
|
10
10
|
import { LOADING_FLAT } from '@/const/message';
|
|
11
11
|
import { TraceNameMap } from '@/const/trace';
|
|
12
|
-
import { useClientDataSWR } from '@/libs/swr';
|
|
12
|
+
import { SWRefreshMethod, useClientDataSWR } from '@/libs/swr';
|
|
13
13
|
import { chatService } from '@/services/chat';
|
|
14
14
|
import { messageService } from '@/services/message';
|
|
15
15
|
import { topicService } from '@/services/topic';
|
|
16
|
-
import { ChatStore } from '@/store/chat';
|
|
16
|
+
import type { ChatStore } from '@/store/chat';
|
|
17
17
|
import { ChatMessage } from '@/types/message';
|
|
18
18
|
import { ChatTopic } from '@/types/topic';
|
|
19
19
|
import { setNamespace } from '@/utils/storeDebug';
|
|
@@ -29,7 +29,7 @@ const SWR_USE_SEARCH_TOPIC = 'SWR_USE_SEARCH_TOPIC';
|
|
|
29
29
|
export interface ChatTopicAction {
|
|
30
30
|
favoriteTopic: (id: string, favState: boolean) => Promise<void>;
|
|
31
31
|
openNewTopicOrSaveTopic: () => Promise<void>;
|
|
32
|
-
refreshTopic:
|
|
32
|
+
refreshTopic: SWRefreshMethod<ChatTopic[]>;
|
|
33
33
|
removeAllTopics: () => Promise<void>;
|
|
34
34
|
removeSessionTopics: () => Promise<void>;
|
|
35
35
|
removeTopic: (id: string) => Promise<void>;
|
|
@@ -78,6 +78,17 @@ export const chatTopic: StateCreator<
|
|
|
78
78
|
messages: messages.map((m) => m.id),
|
|
79
79
|
});
|
|
80
80
|
await refreshTopic();
|
|
81
|
+
// TODO: 优化为乐观更新
|
|
82
|
+
// const params: CreateTopicParams = {
|
|
83
|
+
// sessionId: activeId,
|
|
84
|
+
// title: t('topic.defaultTitle', { ns: 'chat' }),
|
|
85
|
+
// messages: messages.map((m) => m.id),
|
|
86
|
+
// };
|
|
87
|
+
|
|
88
|
+
// const topicId = await refreshTopic({
|
|
89
|
+
// action: async () => topicService.createTopic(params),
|
|
90
|
+
// optimisticData: (data) => topicReducer(data, { type: 'addTopic', value: params }),
|
|
91
|
+
// });
|
|
81
92
|
|
|
82
93
|
// 2. auto summary topic Title
|
|
83
94
|
// we don't need to wait for summary, just let it run async
|
|
@@ -189,9 +200,10 @@ export const chatTopic: StateCreator<
|
|
|
189
200
|
await refreshTopic();
|
|
190
201
|
},
|
|
191
202
|
removeTopic: async (id) => {
|
|
192
|
-
const { activeId, switchTopic, refreshTopic } = get();
|
|
203
|
+
const { activeId, activeTopicId, switchTopic, refreshTopic } = get();
|
|
193
204
|
|
|
194
205
|
// remove messages in the topic
|
|
206
|
+
// TODO: Need to remove because server service don't need to call it
|
|
195
207
|
await messageService.removeMessages(activeId, id);
|
|
196
208
|
|
|
197
209
|
// remove topic
|
|
@@ -199,7 +211,7 @@ export const chatTopic: StateCreator<
|
|
|
199
211
|
await refreshTopic();
|
|
200
212
|
|
|
201
213
|
// switch bach to default topic
|
|
202
|
-
switchTopic();
|
|
214
|
+
if (activeTopicId === id) switchTopic();
|
|
203
215
|
},
|
|
204
216
|
removeUnstarredTopic: async () => {
|
|
205
217
|
const { refreshTopic, switchTopic } = get();
|
|
@@ -226,7 +238,12 @@ export const chatTopic: StateCreator<
|
|
|
226
238
|
updateTopicLoading: (id) => {
|
|
227
239
|
set({ topicLoadingId: id }, false, n('updateTopicLoading'));
|
|
228
240
|
},
|
|
229
|
-
|
|
230
|
-
|
|
241
|
+
// TODO: I don't know why this ts error, so have to ignore it
|
|
242
|
+
// @ts-ignore
|
|
243
|
+
refreshTopic: async (params) => {
|
|
244
|
+
return mutate([SWR_USE_FETCH_TOPIC, get().activeId], params?.action, {
|
|
245
|
+
optimisticData: params?.optimisticData,
|
|
246
|
+
populateCache: false,
|
|
247
|
+
});
|
|
231
248
|
},
|
|
232
249
|
});
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { produce } from 'immer';
|
|
2
|
+
import { expect } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { ChatTopic } from '@/types/topic';
|
|
5
|
+
|
|
6
|
+
import { ChatTopicDispatch, topicReducer } from './reducer';
|
|
7
|
+
|
|
8
|
+
describe('topicReducer', () => {
|
|
9
|
+
let state: ChatTopic[];
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
state = [];
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe('addTopic', () => {
|
|
16
|
+
it('should add a new ChatTopic object to state', () => {
|
|
17
|
+
const payload: ChatTopicDispatch = {
|
|
18
|
+
type: 'addTopic',
|
|
19
|
+
value: {
|
|
20
|
+
title: 'Test Topic',
|
|
21
|
+
sessionId: '',
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const newState = topicReducer(state, payload);
|
|
26
|
+
|
|
27
|
+
expect(newState[0].id).toBeDefined();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('updateTopic', () => {
|
|
32
|
+
it('should update the ChatTopic object in state', () => {
|
|
33
|
+
const topic: ChatTopic = {
|
|
34
|
+
id: '1',
|
|
35
|
+
title: 'Test Topic',
|
|
36
|
+
createdAt: Date.now(),
|
|
37
|
+
updatedAt: Date.now(),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
state.push(topic);
|
|
41
|
+
|
|
42
|
+
const payload: ChatTopicDispatch = {
|
|
43
|
+
type: 'updateTopic',
|
|
44
|
+
id: '1',
|
|
45
|
+
key: 'title',
|
|
46
|
+
value: 'Updated Topic',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const newState = topicReducer(state, payload);
|
|
50
|
+
|
|
51
|
+
expect(newState[0].title).toBe('Updated Topic');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should update the ChatTopic object with correct properties', () => {
|
|
55
|
+
const topic: ChatTopic = {
|
|
56
|
+
id: '1',
|
|
57
|
+
title: 'Test Topic',
|
|
58
|
+
createdAt: Date.now() - 1,
|
|
59
|
+
updatedAt: Date.now() - 1, // 设定比当前时间前面一点
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
state.push(topic);
|
|
63
|
+
|
|
64
|
+
const payload: ChatTopicDispatch = {
|
|
65
|
+
type: 'updateTopic',
|
|
66
|
+
id: '1',
|
|
67
|
+
key: 'title',
|
|
68
|
+
value: 'Updated Topic',
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const newState = topicReducer(state, payload);
|
|
72
|
+
|
|
73
|
+
expect(newState[0].updatedAt).toBeGreaterThan(topic.updatedAt);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe('deleteTopic', () => {
|
|
78
|
+
it('should delete the specified ChatTopic object from state', () => {
|
|
79
|
+
const topic: ChatTopic = {
|
|
80
|
+
id: '1',
|
|
81
|
+
title: 'Test Topic',
|
|
82
|
+
createdAt: Date.now(),
|
|
83
|
+
updatedAt: Date.now(),
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
state.push(topic);
|
|
87
|
+
|
|
88
|
+
const payload: ChatTopicDispatch = {
|
|
89
|
+
type: 'deleteTopic',
|
|
90
|
+
id: '1',
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const newState = topicReducer(state, payload);
|
|
94
|
+
|
|
95
|
+
expect(newState).toEqual([]);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe('default', () => {
|
|
100
|
+
it('should return the original state object', () => {
|
|
101
|
+
const payload = {
|
|
102
|
+
type: 'unknown',
|
|
103
|
+
} as unknown as ChatTopicDispatch;
|
|
104
|
+
|
|
105
|
+
const newState = topicReducer(state, payload);
|
|
106
|
+
|
|
107
|
+
expect(newState).toBe(state);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('produce', () => {
|
|
112
|
+
it('should generate immutable state object', () => {
|
|
113
|
+
const payload: ChatTopicDispatch = {
|
|
114
|
+
type: 'addTopic',
|
|
115
|
+
value: {
|
|
116
|
+
title: 'Test Topic',
|
|
117
|
+
sessionId: '1',
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const newState = topicReducer(state, payload);
|
|
122
|
+
|
|
123
|
+
expect(newState).not.toBe(state);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should not modify the original state object', () => {
|
|
127
|
+
const payload: ChatTopicDispatch = {
|
|
128
|
+
type: 'addTopic',
|
|
129
|
+
value: {
|
|
130
|
+
title: 'Test Topic',
|
|
131
|
+
|
|
132
|
+
sessionId: '123',
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const newState = topicReducer(state, payload);
|
|
137
|
+
|
|
138
|
+
expect(state).toEqual([]);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { produce } from 'immer';
|
|
2
|
+
|
|
3
|
+
import { CreateTopicParams } from '@/services/topic/type';
|
|
4
|
+
import { ChatTopic } from '@/types/topic';
|
|
5
|
+
|
|
6
|
+
interface AddChatTopicAction {
|
|
7
|
+
type: 'addTopic';
|
|
8
|
+
value: CreateTopicParams;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface UpdateChatTopicAction {
|
|
12
|
+
id: string;
|
|
13
|
+
key: keyof ChatTopic;
|
|
14
|
+
type: 'updateTopic';
|
|
15
|
+
value: any;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface DeleteChatTopicAction {
|
|
19
|
+
id: string;
|
|
20
|
+
type: 'deleteTopic';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type ChatTopicDispatch = AddChatTopicAction | UpdateChatTopicAction | DeleteChatTopicAction;
|
|
24
|
+
|
|
25
|
+
export const topicReducer = (state: ChatTopic[] = [], payload: ChatTopicDispatch): ChatTopic[] => {
|
|
26
|
+
switch (payload.type) {
|
|
27
|
+
case 'addTopic': {
|
|
28
|
+
return produce(state, (draftState) => {
|
|
29
|
+
draftState.unshift({
|
|
30
|
+
...payload.value,
|
|
31
|
+
createdAt: Date.now(),
|
|
32
|
+
id: Date.now().toString(),
|
|
33
|
+
sessionId: payload.value.sessionId ? payload.value.sessionId : undefined,
|
|
34
|
+
updatedAt: Date.now(),
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
case 'updateTopic': {
|
|
40
|
+
return produce(state, (draftState) => {
|
|
41
|
+
const { key, value, id } = payload;
|
|
42
|
+
const topicIndex = draftState.findIndex((topic) => topic.id === id);
|
|
43
|
+
|
|
44
|
+
if (topicIndex !== -1) {
|
|
45
|
+
const updatedTopic = { ...draftState[topicIndex] };
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
updatedTopic[key] = value;
|
|
48
|
+
draftState[topicIndex] = updatedTopic;
|
|
49
|
+
updatedTopic.updatedAt = Date.now();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
case 'deleteTopic': {
|
|
55
|
+
return produce(state, (draftState) => {
|
|
56
|
+
const topicIndex = draftState.findIndex((topic) => topic.id === payload.id);
|
|
57
|
+
if (topicIndex !== -1) {
|
|
58
|
+
draftState.splice(topicIndex, 1);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
default: {
|
|
64
|
+
return state;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
@@ -6,6 +6,16 @@ import { currentLLMSettings, getProviderConfigById } from './settings';
|
|
|
6
6
|
const isProviderEnabled = (provider: GlobalLLMProviderKey) => (s: GlobalStore) =>
|
|
7
7
|
getProviderConfigById(provider)(s)?.enabled || false;
|
|
8
8
|
|
|
9
|
+
const isProviderEndpointNotEmpty = (provider: GlobalLLMProviderKey | string) => (s: GlobalStore) =>
|
|
10
|
+
!!getProviderConfigById(provider)(s)?.endpoint;
|
|
11
|
+
|
|
12
|
+
const isProviderFetchOnClient = (provider: GlobalLLMProviderKey | string) => (s: GlobalStore) => {
|
|
13
|
+
const config = getProviderConfigById(provider)(s);
|
|
14
|
+
if (typeof config?.fetchOnClient !== 'undefined') return config?.fetchOnClient;
|
|
15
|
+
|
|
16
|
+
return isProviderEndpointNotEmpty(provider)(s);
|
|
17
|
+
};
|
|
18
|
+
|
|
9
19
|
const getCustomModelCard =
|
|
10
20
|
({ id, provider }: { id?: string; provider?: string }) =>
|
|
11
21
|
(s: GlobalStore) => {
|
|
@@ -46,6 +56,9 @@ export const modelConfigSelectors = {
|
|
|
46
56
|
isAutoFetchModelsEnabled,
|
|
47
57
|
isAzureEnabled,
|
|
48
58
|
isProviderEnabled,
|
|
59
|
+
isProviderEndpointNotEmpty,
|
|
60
|
+
isProviderFetchOnClient,
|
|
61
|
+
|
|
49
62
|
ollamaConfig,
|
|
50
63
|
|
|
51
64
|
openAIConfig,
|
|
@@ -6,7 +6,7 @@ import { StateCreator } from 'zustand/vanilla';
|
|
|
6
6
|
|
|
7
7
|
import { message } from '@/components/AntdStaticMethods';
|
|
8
8
|
import { INBOX_SESSION_ID } from '@/const/session';
|
|
9
|
-
import { useClientDataSWR } from '@/libs/swr';
|
|
9
|
+
import { SWRRefreshParams, useClientDataSWR } from '@/libs/swr';
|
|
10
10
|
import { sessionService } from '@/services/session';
|
|
11
11
|
import { useGlobalStore } from '@/store/global';
|
|
12
12
|
import { settingsSelectors } from '@/store/global/selectors';
|
|
@@ -51,10 +51,7 @@ export interface SessionAction {
|
|
|
51
51
|
/**
|
|
52
52
|
* re-fetch the data
|
|
53
53
|
*/
|
|
54
|
-
refreshSessions: (params?:
|
|
55
|
-
action: () => Promise<void>;
|
|
56
|
-
optimisticData?: (data: ChatSessionList) => ChatSessionList;
|
|
57
|
-
}) => Promise<void>;
|
|
54
|
+
refreshSessions: (params?: SWRRefreshParams<ChatSessionList>) => Promise<void>;
|
|
58
55
|
|
|
59
56
|
/**
|
|
60
57
|
* remove session
|
|
@@ -145,6 +142,8 @@ export const createSessionSlice: StateCreator<
|
|
|
145
142
|
},
|
|
146
143
|
// 乐观更新
|
|
147
144
|
optimisticData: produce((draft) => {
|
|
145
|
+
if (!draft) return;
|
|
146
|
+
|
|
148
147
|
const session = draft.all.find((i) => i.id === sessionId);
|
|
149
148
|
if (!session) return;
|
|
150
149
|
|
package/vercel.json
CHANGED