Skip to content

Commit ef8cd56

Browse files
authored
fix: switch server assistant and session session unchanged (#540)
* fix: switch server assistant and session session unchanged * docs: update notes
1 parent 5ef06bf commit ef8cd56

9 files changed

Lines changed: 243 additions & 224 deletions

File tree

docs/content.en/docs/release-notes/_index.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,21 @@ Information about release notes of Coco Server is provided here.
2929

3030
### 🐛 Bug fix
3131

32+
- fix: solve the problem of modifying the assistant in the chat #476
3233
- fix: several issues around search #502
3334
- fix: fixed the newly created session has no title when it is deleted #511
3435
- fix: loading chat history for potential empty attachments
3536
- fix: datasource & MCP list synchronization update #521
37+
- fix: app icon & category icon #529
3638
- fix: show only enabled datasource & MCP list
39+
- fix: server image loading failure #534
3740
- fix: panic when fetching app metadata on Windows #538
41+
- fix: service switching error #539
42+
- fix: switch server assistant and session session unchanged #540
3843

3944
### ✈️ Improvements
4045

4146
- chore: adjust list error message #475
42-
- fix: solve the problem of modifying the assistant in the chat #476
4347
- chore: refine wording on search failure
4448
- chore:search and MCP show hidden logic #494
4549
- chore: greetings show hidden logic #496
@@ -54,12 +58,9 @@ Information about release notes of Coco Server is provided here.
5458
- refactor: optimizing list styles in markdown content #520
5559
- feat: add a component for text reading aloud #522
5660
- style: history component styles #528
57-
- fix: app icon & category icon #529
5861
- style: search error styles #533
59-
- fix: server image loading failure #534
6062
- chore: skip register server that not logged in #536
6163
- refactor: service info related components #537
62-
- fix: service switching error #539
6364
- chore: chat content can be copied #539
6465

6566
## 0.4.0 (2025-04-27)
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { useRef } from "react";
2+
3+
import { Post } from "@/api/axiosRequest";
4+
import platformAdapter from "@/utils/platformAdapter";
5+
import { useConnectStore } from "@/stores/connectStore";
6+
import { useAppStore } from "@/stores/appStore";
7+
8+
interface AssistantFetcherProps {
9+
debounceKeyword?: string;
10+
assistantIDs?: string[];
11+
}
12+
13+
export const AssistantFetcher = ({
14+
debounceKeyword = "",
15+
assistantIDs = [],
16+
}: AssistantFetcherProps) => {
17+
const isTauri = useAppStore((state) => state.isTauri);
18+
19+
const currentService = useConnectStore((state) => state.currentService);
20+
21+
const currentAssistant = useConnectStore((state) => state.currentAssistant);
22+
const setCurrentAssistant = useConnectStore((state) => {
23+
return state.setCurrentAssistant;
24+
});
25+
26+
const lastServerId = useRef<string | null>(null);
27+
28+
const fetchAssistant = async (params: {
29+
current: number;
30+
pageSize: number;
31+
}) => {
32+
try {
33+
const { pageSize, current } = params;
34+
35+
const from = (current - 1) * pageSize;
36+
const size = pageSize;
37+
38+
let response: any;
39+
40+
const body: Record<string, any> = {
41+
serverId: currentService?.id,
42+
from,
43+
size,
44+
};
45+
46+
body.query = {
47+
bool: {
48+
must: [{ term: { enabled: true } }],
49+
},
50+
};
51+
52+
if (debounceKeyword) {
53+
body.query.bool.must.push({
54+
query_string: {
55+
fields: ["combined_fulltext"],
56+
query: debounceKeyword,
57+
fuzziness: "AUTO",
58+
fuzzy_prefix_length: 2,
59+
fuzzy_max_expansions: 10,
60+
fuzzy_transpositions: true,
61+
allow_leading_wildcard: false,
62+
},
63+
});
64+
}
65+
if (assistantIDs.length > 0) {
66+
body.query.bool.must.push({
67+
terms: {
68+
id: assistantIDs.map((id) => id),
69+
},
70+
});
71+
}
72+
73+
if (isTauri) {
74+
if (!currentService?.id) {
75+
throw new Error("currentService is undefined");
76+
}
77+
78+
response = await platformAdapter.commands("assistant_search", body);
79+
} else {
80+
const [error, res] = await Post(`/assistant/_search`, body);
81+
82+
if (error) {
83+
throw new Error(error);
84+
}
85+
86+
response = res;
87+
}
88+
89+
let assistantList = response?.hits?.hits ?? [];
90+
91+
console.log("assistantList", assistantList);
92+
93+
if (
94+
!currentAssistant?._id ||
95+
currentService?.id !== lastServerId.current
96+
) {
97+
setCurrentAssistant(assistantList[0]);
98+
}
99+
lastServerId.current = currentService?.id;
100+
101+
return {
102+
total: response.hits.total.value,
103+
list: assistantList,
104+
};
105+
} catch (error) {
106+
setCurrentAssistant(null);
107+
108+
console.error("assistant_search", error);
109+
110+
return {
111+
total: 0,
112+
list: [],
113+
};
114+
}
115+
};
116+
117+
return { fetchAssistant };
118+
};

src/components/Assistant/AssistantList.tsx

Lines changed: 9 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useRef, useCallback, useMemo } from "react";
1+
import { useState, useRef, useCallback } from "react";
22
import {
33
ChevronDownIcon,
44
RefreshCw,
@@ -10,40 +10,28 @@ import { useTranslation } from "react-i18next";
1010
import { isNil } from "lodash-es";
1111
import { Popover, PopoverButton, PopoverPanel } from "@headlessui/react";
1212
import {
13-
useAsyncEffect,
1413
useDebounce,
1514
useKeyPress,
1615
usePagination,
17-
useReactive,
1816
} from "ahooks";
1917
import clsx from "clsx";
2018

21-
import { useAppStore } from "@/stores/appStore";
2219
import logoImg from "@/assets/icon.svg";
23-
import platformAdapter from "@/utils/platformAdapter";
2420
import VisibleKey from "@/components/Common/VisibleKey";
2521
import { useConnectStore } from "@/stores/connectStore";
2622
import FontIcon from "@/components/Common/Icons/FontIcon";
27-
import { useChatStore } from "@/stores/chatStore";
2823
import { useShortcutsStore } from "@/stores/shortcutsStore";
29-
import { Post } from "@/api/axiosRequest";
30-
import NoDataImage from "../Common/NoDataImage";
31-
import PopoverInput from "../Common/PopoverInput";
24+
import NoDataImage from "@/components/Common/NoDataImage";
25+
import PopoverInput from "@/components/Common/PopoverInput";
26+
import { AssistantFetcher } from "./AssistantFetcher";
3227

3328
interface AssistantListProps {
3429
assistantIDs?: string[];
3530
}
3631

37-
interface State {
38-
allAssistants: any[];
39-
}
40-
4132
export function AssistantList({ assistantIDs = [] }: AssistantListProps) {
4233
const { t } = useTranslation();
43-
const { connected } = useChatStore();
4434

45-
const isTauri = useAppStore((state) => state.isTauri);
46-
const setAssistantList = useConnectStore((state) => state.setAssistantList);
4735
const currentService = useConnectStore((state) => state.currentService);
4836
const currentAssistant = useConnectStore((state) => state.currentAssistant);
4937
const setCurrentAssistant = useConnectStore((state) => {
@@ -57,130 +45,15 @@ export function AssistantList({ assistantIDs = [] }: AssistantListProps) {
5745
const searchInputRef = useRef<HTMLInputElement>(null);
5846
const [keyword, setKeyword] = useState("");
5947
const debounceKeyword = useDebounce(keyword, { wait: 500 });
60-
const state = useReactive<State>({
61-
allAssistants: [],
62-
});
63-
64-
const currentServiceId = useMemo(() => {
65-
return currentService?.id;
66-
}, [connected, currentService?.id]);
67-
68-
const fetchAssistant = async (params: {
69-
current: number;
70-
pageSize: number;
71-
}) => {
72-
try {
73-
const { pageSize, current } = params;
74-
75-
const from = (current - 1) * pageSize;
76-
const size = pageSize;
77-
78-
let response: any;
79-
80-
const body: Record<string, any> = {
81-
serverId: currentServiceId,
82-
from,
83-
size,
84-
};
85-
86-
body.query = {
87-
bool: {
88-
must: [{ term: { enabled: true } }],
89-
},
90-
};
91-
92-
if (debounceKeyword) {
93-
body.query.bool.must.push({
94-
query_string: {
95-
fields: ["combined_fulltext"],
96-
query: debounceKeyword,
97-
fuzziness: "AUTO",
98-
fuzzy_prefix_length: 2,
99-
fuzzy_max_expansions: 10,
100-
fuzzy_transpositions: true,
101-
allow_leading_wildcard: false,
102-
},
103-
});
104-
}
105-
if (assistantIDs.length > 0) {
106-
body.query.bool.must.push({
107-
terms: {
108-
id: assistantIDs.map((id) => id),
109-
},
110-
});
111-
}
112-
113-
if (isTauri) {
114-
if (!currentServiceId) {
115-
throw new Error("currentServiceId is undefined");
116-
}
117-
118-
response = await platformAdapter.commands("assistant_search", body);
119-
} else {
120-
const [error, res] = await Post(`/assistant/_search`, body);
121-
122-
if (error) {
123-
throw new Error(error);
124-
}
125-
126-
response = res;
127-
}
128-
129-
let assistantList = response?.hits?.hits ?? [];
130-
131-
console.log("assistantList", assistantList);
132-
133-
for (const item of assistantList) {
134-
const index = state.allAssistants.findIndex((allItem: any) => {
135-
return item._id === allItem._id;
136-
});
13748

138-
if (index === -1) {
139-
state.allAssistants.push(item);
140-
} else {
141-
state.allAssistants[index] = item;
142-
}
143-
}
144-
145-
//console.log("state.allAssistants", state.allAssistants);
146-
147-
const matched = state.allAssistants.find((item: any) => {
148-
return item._id === currentAssistant?._id;
149-
});
150-
151-
//console.log("matched", matched);
152-
153-
if (matched) {
154-
setCurrentAssistant(matched);
155-
} else {
156-
setCurrentAssistant(assistantList[0]);
157-
}
158-
159-
return {
160-
total: response.hits.total.value,
161-
list: assistantList,
162-
};
163-
} catch (error) {
164-
setCurrentAssistant(null);
165-
166-
console.error("assistant_search", error);
167-
168-
return {
169-
total: 0,
170-
list: [],
171-
};
172-
}
173-
};
174-
175-
useAsyncEffect(async () => {
176-
const data = await fetchAssistant({ current: 1, pageSize: 1000 });
177-
178-
setAssistantList(data.list);
179-
}, [currentServiceId]);
49+
const { fetchAssistant } = AssistantFetcher({
50+
debounceKeyword,
51+
assistantIDs,
52+
});
18053

18154
const { pagination, runAsync } = usePagination(fetchAssistant, {
18255
defaultPageSize: 5,
183-
refreshDeps: [currentServiceId, debounceKeyword],
56+
refreshDeps: [currentService?.id, debounceKeyword],
18457
onSuccess(data) {
18558
setAssistants(data.list);
18659
},

src/components/Assistant/Chat.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ const ChatAI = memo(
7575
const { curChatEnd, setCurChatEnd, connected, setConnected } =
7676
useChatStore();
7777

78-
const currentService = useConnectStore((state) => state.currentService);
7978
const visibleStartPage = useConnectStore((state) => {
8079
return state.visibleStartPage;
8180
});
@@ -151,7 +150,6 @@ const ChatAI = memo(
151150
handleRename,
152151
handleDelete,
153152
} = useChatActions(
154-
currentService?.id,
155153
setActiveChat,
156154
setCurChatEnd,
157155
setTimedoutShow,
@@ -366,6 +364,7 @@ const ChatAI = memo(
366364
loadingStep={loadingStep}
367365
timedoutShow={timedoutShow}
368366
Question={Question}
367+
assistantIDs={assistantIDs}
369368
handleSendMessage={(value) =>
370369
handleSendMessage(value, activeChat)
371370
}

0 commit comments

Comments
 (0)