Skip to content

Commit 382f89a

Browse files
authored
fix: independent chat app has no datasources (#554)
* fix: independent chat window has no data * docs: update notes
1 parent 32c7cc5 commit 382f89a

6 files changed

Lines changed: 160 additions & 226 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Information about release notes of Coco Server is provided here.
4444
- fix: secondary page cannot be searched #551
4545
- fix: the scroll button is not displayed by default #552
4646
- fix: suggestion list position #553
47+
- fix: independent chat window has no data #554
4748

4849
### ✈️ Improvements
4950

src/components/Assistant/ChatHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export function ChatHeader({
9898
onClick={clearChat}
9999
className="p-2 py-1 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800"
100100
>
101-
<VisibleKey shortcut={newSession} onKeyPress={clearChat}>
101+
<VisibleKey shortcutClassName="top-2.5" shortcut={newSession} onKeyPress={clearChat}>
102102
<MessageSquarePlus className="h-4 w-4 relative top-0.5" />
103103
</VisibleKey>
104104
</button>

src/components/Search/DocumentDetail.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export const DocumentDetail: React.FC<DocumentDetailProps> = ({ document }) => {
4343
};
4444

4545
return (
46-
<div className="p-3">
46+
<div className="p-3 user-select-text">
4747
{/* <div className="font-normal text-xs text-[#666] dark:text-[#999] mb-2">
4848
{t("search.document.details")}
4949
</div> */}

src/components/Search/InputBox.tsx

Lines changed: 155 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Brain } from "lucide-react";
2-
import { useCallback, useEffect, useRef, useState } from "react";
2+
import { useCallback, useEffect, useRef, useState, useMemo } from "react";
33
import { useTranslation } from "react-i18next";
44
import clsx from "clsx";
55
import { useKeyPress } from "ahooks";
@@ -23,8 +23,11 @@ import ConnectionError from "./ConnectionError";
2323
import SearchIcons from "./SearchIcons";
2424
import ChatIcons from "./ChatIcons";
2525
// import AiSummaryIcon from "../Common/Icons/AiSummaryIcon";
26+
import { Post } from "@/api/axiosRequest";
27+
import platformAdapter from "@/utils/platformAdapter";
2628

2729
interface ChatInputProps {
30+
isTauri: boolean;
2831
onSend: (message: string) => void;
2932
disabled: boolean;
3033
disabledChange: () => void;
@@ -40,22 +43,6 @@ interface ChatInputProps {
4043
isMCPActive: boolean;
4144
setIsMCPActive: () => void;
4245
isChatPage?: boolean;
43-
getDataSourcesByServer: (
44-
serverId: string,
45-
options?: {
46-
from?: number;
47-
size?: number;
48-
query?: string;
49-
}
50-
) => Promise<DataSource[]>;
51-
getMCPByServer: (
52-
serverId: string,
53-
options?: {
54-
from?: number;
55-
size?: number;
56-
query?: string;
57-
}
58-
) => Promise<DataSource[]>;
5946
setupWindowFocusListener: (callback: () => void) => Promise<() => void>;
6047
checkScreenPermission: () => Promise<boolean>;
6148
requestScreenPermission: () => void;
@@ -75,6 +62,7 @@ interface ChatInputProps {
7562
}
7663

7764
export default function ChatInput({
65+
isTauri,
7866
onSend,
7967
disabled,
8068
changeMode,
@@ -90,8 +78,6 @@ export default function ChatInput({
9078
isMCPActive,
9179
setIsMCPActive,
9280
isChatPage = false,
93-
getDataSourcesByServer,
94-
getMCPByServer,
9581
setupWindowFocusListener,
9682
hasModules = [],
9783
searchPlaceholder,
@@ -254,6 +240,156 @@ export default function ChatInput({
254240

255241
const source = currentAssistant?._source;
256242

243+
const assistantConfig = useMemo(() => {
244+
return {
245+
datasourceEnabled: source?.datasource?.enabled,
246+
datasourceVisible: source?.datasource?.visible,
247+
datasourceIds: source?.datasource?.ids,
248+
mcpEnabled: source?.mcp_servers?.enabled,
249+
mcpVisible: source?.mcp_servers?.visible,
250+
mcpIds: source?.mcp_servers?.ids,
251+
};
252+
}, [currentAssistant]);
253+
254+
const getDataSourcesByServer = useCallback(
255+
async (
256+
serverId: string,
257+
options?: {
258+
from?: number;
259+
size?: number;
260+
query?: string;
261+
}
262+
): Promise<DataSource[]> => {
263+
if (
264+
!(
265+
assistantConfig.datasourceEnabled && assistantConfig.datasourceVisible
266+
)
267+
) {
268+
return [];
269+
}
270+
271+
const body: Record<string, any> = {
272+
id: serverId,
273+
from: options?.from || 0,
274+
size: options?.size || 1000,
275+
};
276+
277+
body.query = {
278+
bool: {
279+
must: [{ term: { enabled: true } }],
280+
},
281+
};
282+
283+
if (options?.query) {
284+
body.query.bool.must.push({
285+
query_string: {
286+
fields: ["combined_fulltext"],
287+
query: options?.query,
288+
fuzziness: "AUTO",
289+
fuzzy_prefix_length: 2,
290+
fuzzy_max_expansions: 10,
291+
fuzzy_transpositions: true,
292+
allow_leading_wildcard: false,
293+
},
294+
});
295+
}
296+
297+
let response: any;
298+
if (isTauri) {
299+
response = await platformAdapter.invokeBackend("datasource_search", {
300+
id: serverId,
301+
options: body,
302+
});
303+
} else {
304+
const [error, res]: any = await Post("/datasource/_search", body);
305+
if (error) {
306+
console.error("_search", error);
307+
return [];
308+
}
309+
response = res?.hits?.hits?.map((item: any) => {
310+
return {
311+
...item,
312+
id: item._source.id,
313+
name: item._source.name,
314+
};
315+
});
316+
}
317+
let ids = assistantConfig.datasourceIds;
318+
if (Array.isArray(ids) && ids.length > 0 && !ids.includes("*")) {
319+
response = response?.filter((item: any) => ids.includes(item.id));
320+
}
321+
return response || [];
322+
},
323+
[assistantConfig]
324+
);
325+
326+
const getMCPByServer = useCallback(
327+
async (
328+
serverId: string,
329+
options?: {
330+
from?: number;
331+
size?: number;
332+
query?: string;
333+
}
334+
): Promise<DataSource[]> => {
335+
if (!(assistantConfig.mcpEnabled && assistantConfig.mcpVisible)) {
336+
return [];
337+
}
338+
const body: Record<string, any> = {
339+
id: serverId,
340+
from: options?.from || 0,
341+
size: options?.size || 1000,
342+
};
343+
body.query = {
344+
bool: {
345+
must: [{ term: { enabled: true } }],
346+
},
347+
};
348+
349+
if (options?.query) {
350+
body.query.bool.must.push({
351+
query_string: {
352+
fields: ["combined_fulltext"],
353+
query: options?.query,
354+
fuzziness: "AUTO",
355+
fuzzy_prefix_length: 2,
356+
fuzzy_max_expansions: 10,
357+
fuzzy_transpositions: true,
358+
allow_leading_wildcard: false,
359+
},
360+
});
361+
}
362+
363+
let response: any;
364+
if (isTauri) {
365+
response = await platformAdapter.invokeBackend(
366+
"mcp_server_search",
367+
body
368+
);
369+
} else {
370+
const [error, res]: any = await Post("/mcp_server/_search", body);
371+
if (error) {
372+
console.error("_search", error);
373+
return [];
374+
}
375+
response = res?.hits?.hits?.map((item: any) => {
376+
return {
377+
...item,
378+
id: item._source.id,
379+
name: item._source.name,
380+
};
381+
});
382+
}
383+
let ids = assistantConfig.mcpIds;
384+
if (Array.isArray(ids) && ids.length > 0 && !ids.includes("*")) {
385+
response = response?.filter((item: any) => ids.includes(item.id));
386+
}
387+
return response || [];
388+
},
389+
[assistantConfig]
390+
);
391+
392+
257393
return (
258394
<div className={`w-full relative`}>
259395
<div

0 commit comments

Comments
 (0)