mirror of
https://github.com/infinilabs/coco-app.git
synced 2026-09-01 19:51:52 +02:00
@@ -77,7 +77,8 @@ const ChatAI = memo(
|
||||
clearChat: clearChat,
|
||||
}));
|
||||
|
||||
const { curChatEnd, setCurChatEnd } = useChatStore();
|
||||
const curChatEnd = useChatStore((state) => state.curChatEnd);
|
||||
const setCurChatEnd = useChatStore((state) => state.setCurChatEnd);
|
||||
|
||||
const isTauri = useAppStore((state) => state.isTauri);
|
||||
|
||||
@@ -385,7 +386,6 @@ const ChatAI = memo(
|
||||
<>
|
||||
<ChatContent
|
||||
activeChat={activeChat}
|
||||
curChatEnd={curChatEnd}
|
||||
query_intent={query_intent}
|
||||
tools={tools}
|
||||
fetch_source={fetch_source}
|
||||
@@ -401,7 +401,6 @@ const ChatAI = memo(
|
||||
}
|
||||
getFileUrl={getFileUrl}
|
||||
formatUrl={formatUrl}
|
||||
curSessionIdRef={curSessionIdRef}
|
||||
curIdRef={curIdRef}
|
||||
/>
|
||||
<Splash assistantIDs={assistantIDs} startPage={startPage} />
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ChatMessage } from "@/components/ChatMessage";
|
||||
import { Greetings } from "./Greetings";
|
||||
// import FileList from "@/components/Assistant/FileList";
|
||||
import { useChatScroll } from "@/hooks/useChatScroll";
|
||||
// import { useChatStore } from "@/stores/chatStore";
|
||||
import { useChatStore } from "@/stores/chatStore";
|
||||
import type { Chat, IChunkData } from "@/types/chat";
|
||||
import { useConnectStore } from "@/stores/connectStore";
|
||||
// import SessionFile from "./SessionFile";
|
||||
@@ -13,7 +13,6 @@ import ScrollToBottom from "@/components/Common/ScrollToBottom";
|
||||
|
||||
interface ChatContentProps {
|
||||
activeChat?: Chat;
|
||||
curChatEnd: boolean;
|
||||
query_intent?: IChunkData;
|
||||
tools?: IChunkData;
|
||||
fetch_source?: IChunkData;
|
||||
@@ -27,13 +26,11 @@ interface ChatContentProps {
|
||||
handleSendMessage: (content: string, newChat?: Chat) => void;
|
||||
getFileUrl: (path: string) => string;
|
||||
formatUrl?: (data: any) => string;
|
||||
curSessionIdRef: React.MutableRefObject<string>;
|
||||
curIdRef: React.MutableRefObject<string>;
|
||||
}
|
||||
|
||||
export const ChatContent = ({
|
||||
activeChat,
|
||||
curChatEnd,
|
||||
query_intent,
|
||||
tools,
|
||||
fetch_source,
|
||||
@@ -46,10 +43,7 @@ export const ChatContent = ({
|
||||
Question,
|
||||
handleSendMessage,
|
||||
formatUrl,
|
||||
curSessionIdRef,
|
||||
curIdRef,
|
||||
}: ChatContentProps) => {
|
||||
console.log("curSessionIdRef", curSessionIdRef.current === activeChat?._id);
|
||||
// const sessionId = useConnectStore((state) => state.currentSessionId);
|
||||
const setCurrentSessionId = useConnectStore((state) => {
|
||||
return state.setCurrentSessionId;
|
||||
@@ -65,6 +59,8 @@ export const ChatContent = ({
|
||||
const [isAtBottom, setIsAtBottom] = useState(true);
|
||||
const visibleStartPage = useConnectStore((state) => state.visibleStartPage);
|
||||
|
||||
const curChatEnd = useChatStore((state) => state.curChatEnd);
|
||||
|
||||
useEffect(() => {
|
||||
setIsAtBottom(true);
|
||||
setCurrentSessionId(activeChat?._id);
|
||||
@@ -100,8 +96,6 @@ export const ChatContent = ({
|
||||
setIsAtBottom(isAtBottom);
|
||||
};
|
||||
|
||||
console.log("curIdRef", curIdRef.current);
|
||||
|
||||
return (
|
||||
<div className="flex-1 overflow-hidden flex flex-col justify-between relative user-select-text">
|
||||
<div
|
||||
|
||||
@@ -14,7 +14,7 @@ export function useChatActions(
|
||||
setActiveChat: (chat: Chat | undefined) => void,
|
||||
setCurChatEnd: (value: boolean) => void,
|
||||
setTimedoutShow: (value: boolean) => void,
|
||||
clearAllChunkData: () => void,
|
||||
clearAllChunkData: () => Promise<void>,
|
||||
setQuestion: (value: string) => void,
|
||||
curIdRef: React.MutableRefObject<string>,
|
||||
curSessionIdRef: React.MutableRefObject<string>,
|
||||
@@ -113,19 +113,16 @@ export function useChatActions(
|
||||
serverId: currentService?.id,
|
||||
sessionId: activeChat?._id,
|
||||
queryParams: {
|
||||
message_id: curIdRef.current
|
||||
}
|
||||
message_id: curIdRef.current,
|
||||
},
|
||||
});
|
||||
response = response ? JSON.parse(response) : null;
|
||||
} else {
|
||||
const [_error, res] = await Post(
|
||||
`/chat/${activeChat?._id}/_cancel`,
|
||||
{
|
||||
queryParams: {
|
||||
message_id: curIdRef.current
|
||||
}
|
||||
}
|
||||
);
|
||||
const [_error, res] = await Post(`/chat/${activeChat?._id}/_cancel`, {
|
||||
queryParams: {
|
||||
message_id: curIdRef.current,
|
||||
},
|
||||
});
|
||||
response = res;
|
||||
}
|
||||
console.log("_cancel", response);
|
||||
@@ -185,140 +182,10 @@ export function useChatActions(
|
||||
|
||||
// Modify the clientId generation logic to include the instance ID.
|
||||
const clientId = useMemo(() => {
|
||||
const timestamp = Date.now();
|
||||
const pageType = isChatPage ? "standalone-chat" : "search-chat";
|
||||
return `${pageType}-${timestamp}`;
|
||||
return `${pageType}`;
|
||||
}, [isChatPage]);
|
||||
|
||||
const prepareChatSession = (async (value: string) => {
|
||||
// 1. Cleaning and preparation
|
||||
await clearAllChunkData();
|
||||
|
||||
// 2. Update the status again
|
||||
changeInput && changeInput("");
|
||||
setCurChatEnd(false);
|
||||
setVisibleStartPage(false);
|
||||
setTimedoutShow(false);
|
||||
setQuestion(value);
|
||||
|
||||
// 3. Set up the listener first
|
||||
await setupListeners();
|
||||
});
|
||||
|
||||
const createNewChat = useCallback(
|
||||
async (value: string = "") => {
|
||||
if (!value) return;
|
||||
|
||||
await prepareChatSession(value);
|
||||
|
||||
const queryParams = {
|
||||
search: isSearchActive,
|
||||
deep_thinking: isDeepThinkActive,
|
||||
mcp: isMCPActive,
|
||||
datasource: sourceDataIds?.join(",") || "",
|
||||
mcp_servers: MCPIds?.join(",") || "",
|
||||
assistant_id: currentAssistant?._id || "",
|
||||
};
|
||||
|
||||
if (isTauri) {
|
||||
if (!currentService?.id) return;
|
||||
await platformAdapter.commands("chat_create", {
|
||||
serverId: currentService?.id,
|
||||
message: value,
|
||||
queryParams,
|
||||
clientId: `chat-stream-${clientId}`,
|
||||
});
|
||||
console.log("_create end", value);
|
||||
resetChatState();
|
||||
} else {
|
||||
await streamPost({
|
||||
url: "/chat/_create",
|
||||
body: { message: value },
|
||||
queryParams,
|
||||
onMessage: (line) => {
|
||||
console.log("⏳", line);
|
||||
handleChatCreateStreamMessage(line);
|
||||
// append to chat box
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
[
|
||||
isTauri,
|
||||
currentService?.id,
|
||||
sourceDataIds,
|
||||
MCPIds,
|
||||
isSearchActive,
|
||||
isDeepThinkActive,
|
||||
isMCPActive,
|
||||
currentAssistant,
|
||||
chatClose,
|
||||
clientId,
|
||||
]
|
||||
);
|
||||
|
||||
const sendMessage = useCallback(
|
||||
async (content: string, newChat: Chat) => {
|
||||
if (!newChat?._id || !content) return;
|
||||
|
||||
await prepareChatSession(content);
|
||||
|
||||
const queryParams = {
|
||||
search: isSearchActive,
|
||||
deep_thinking: isDeepThinkActive,
|
||||
mcp: isMCPActive,
|
||||
datasource: sourceDataIds?.join(",") || "",
|
||||
mcp_servers: MCPIds?.join(",") || "",
|
||||
assistant_id: currentAssistant?._id || "",
|
||||
};
|
||||
|
||||
if (isTauri) {
|
||||
if (!currentService?.id) return;
|
||||
await platformAdapter.commands("chat_chat", {
|
||||
serverId: currentService?.id,
|
||||
sessionId: newChat?._id,
|
||||
queryParams,
|
||||
message: content,
|
||||
clientId: `chat-stream-${clientId}`,
|
||||
});
|
||||
console.log("chat_chat end", content);
|
||||
resetChatState();
|
||||
} else {
|
||||
await streamPost({
|
||||
url: `/chat/${newChat?._id}/_chat`,
|
||||
body: { message: content },
|
||||
queryParams,
|
||||
onMessage: (line) => {
|
||||
console.log("line", line);
|
||||
handleChatCreateStreamMessage(line);
|
||||
// append to chat box
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
[
|
||||
isTauri,
|
||||
currentService?.id,
|
||||
sourceDataIds,
|
||||
MCPIds,
|
||||
isSearchActive,
|
||||
isDeepThinkActive,
|
||||
isMCPActive,
|
||||
changeInput,
|
||||
currentAssistant,
|
||||
clientId,
|
||||
]
|
||||
);
|
||||
|
||||
const handleSendMessage = useCallback(
|
||||
async (content: string, activeChat?: Chat) => {
|
||||
if (!activeChat?._id || !content) return;
|
||||
|
||||
await chatHistory(activeChat, (chat) => sendMessage(content, chat));
|
||||
},
|
||||
[chatHistory, sendMessage]
|
||||
);
|
||||
|
||||
const handleChatCreateStreamMessage = useCallback(
|
||||
(msg: string) => {
|
||||
if (
|
||||
@@ -379,12 +246,12 @@ export function useChatActions(
|
||||
[changeInput, setActiveChat, setCurChatEnd, setVisibleStartPage]
|
||||
);
|
||||
|
||||
const setupListeners = useCallback(async () => {
|
||||
const setupListeners = useCallback(async (timestamp: number) => {
|
||||
cleanupListeners();
|
||||
|
||||
console.log("setupListeners", clientId);
|
||||
console.log("setupListeners", clientId, timestamp);
|
||||
const unlisten_chat_message = await platformAdapter.listenEvent(
|
||||
`chat-stream-${clientId}`,
|
||||
`chat-stream-${clientId}-${timestamp}`,
|
||||
(event) => {
|
||||
const msg = event.payload as string;
|
||||
try {
|
||||
@@ -419,6 +286,147 @@ export function useChatActions(
|
||||
};
|
||||
}, [currentService?.id, clientId, handleChatCreateStreamMessage]);
|
||||
|
||||
const prepareChatSession = useCallback(
|
||||
async (value: string, timestamp: number) => {
|
||||
// 1. Cleaning and preparation
|
||||
await clearAllChunkData();
|
||||
|
||||
// 2. Update the status again
|
||||
await new Promise<void>((resolve) => {
|
||||
changeInput && changeInput("");
|
||||
setVisibleStartPage(false);
|
||||
setTimedoutShow(false);
|
||||
setQuestion(value);
|
||||
setCurChatEnd(false);
|
||||
setTimeout(resolve, 0);
|
||||
});
|
||||
|
||||
// 4. Set up the listener first
|
||||
await setupListeners(timestamp);
|
||||
},
|
||||
[setupListeners]
|
||||
);
|
||||
|
||||
const createNewChat = useCallback(
|
||||
async (value: string = "") => {
|
||||
if (!value) return;
|
||||
|
||||
const timestamp = Date.now();
|
||||
|
||||
await prepareChatSession(value, timestamp);
|
||||
|
||||
const queryParams = {
|
||||
search: isSearchActive,
|
||||
deep_thinking: isDeepThinkActive,
|
||||
mcp: isMCPActive,
|
||||
datasource: sourceDataIds?.join(",") || "",
|
||||
mcp_servers: MCPIds?.join(",") || "",
|
||||
assistant_id: currentAssistant?._id || "",
|
||||
};
|
||||
|
||||
if (isTauri) {
|
||||
if (!currentService?.id) return;
|
||||
console.log("chat_create", clientId, timestamp);
|
||||
await platformAdapter.commands("chat_create", {
|
||||
serverId: currentService?.id,
|
||||
message: value,
|
||||
queryParams,
|
||||
clientId: `chat-stream-${clientId}-${timestamp}`,
|
||||
});
|
||||
console.log("_create end", value);
|
||||
resetChatState();
|
||||
} else {
|
||||
await streamPost({
|
||||
url: "/chat/_create",
|
||||
body: { message: value },
|
||||
queryParams,
|
||||
onMessage: (line) => {
|
||||
console.log("⏳", line);
|
||||
handleChatCreateStreamMessage(line);
|
||||
// append to chat box
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
[
|
||||
isTauri,
|
||||
currentService?.id,
|
||||
sourceDataIds,
|
||||
MCPIds,
|
||||
isSearchActive,
|
||||
isDeepThinkActive,
|
||||
isMCPActive,
|
||||
currentAssistant,
|
||||
chatClose,
|
||||
clientId,
|
||||
]
|
||||
);
|
||||
|
||||
const sendMessage = useCallback(
|
||||
async (content: string, newChat: Chat) => {
|
||||
if (!newChat?._id || !content) return;
|
||||
|
||||
const timestamp = Date.now();
|
||||
|
||||
await prepareChatSession(content, timestamp);
|
||||
|
||||
const queryParams = {
|
||||
search: isSearchActive,
|
||||
deep_thinking: isDeepThinkActive,
|
||||
mcp: isMCPActive,
|
||||
datasource: sourceDataIds?.join(",") || "",
|
||||
mcp_servers: MCPIds?.join(",") || "",
|
||||
assistant_id: currentAssistant?._id || "",
|
||||
};
|
||||
|
||||
if (isTauri) {
|
||||
if (!currentService?.id) return;
|
||||
console.log("chat_chat", clientId, timestamp);
|
||||
await platformAdapter.commands("chat_chat", {
|
||||
serverId: currentService?.id,
|
||||
sessionId: newChat?._id,
|
||||
queryParams,
|
||||
message: content,
|
||||
clientId: `chat-stream-${clientId}-${timestamp}`,
|
||||
});
|
||||
console.log("chat_chat end", content, clientId);
|
||||
resetChatState();
|
||||
} else {
|
||||
await streamPost({
|
||||
url: `/chat/${newChat?._id}/_chat`,
|
||||
body: { message: content },
|
||||
queryParams,
|
||||
onMessage: (line) => {
|
||||
console.log("line", line);
|
||||
handleChatCreateStreamMessage(line);
|
||||
// append to chat box
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
[
|
||||
isTauri,
|
||||
currentService?.id,
|
||||
sourceDataIds,
|
||||
MCPIds,
|
||||
isSearchActive,
|
||||
isDeepThinkActive,
|
||||
isMCPActive,
|
||||
changeInput,
|
||||
currentAssistant,
|
||||
clientId,
|
||||
]
|
||||
);
|
||||
|
||||
const handleSendMessage = useCallback(
|
||||
async (content: string, activeChat?: Chat) => {
|
||||
if (!activeChat?._id || !content) return;
|
||||
|
||||
await chatHistory(activeChat, (chat) => sendMessage(content, chat));
|
||||
},
|
||||
[chatHistory, sendMessage]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isTauri || !currentService?.id) return;
|
||||
|
||||
|
||||
@@ -489,7 +489,7 @@
|
||||
},
|
||||
"tray": {
|
||||
"showCoco": "Show Coco",
|
||||
"settings": "Settings...",
|
||||
"settings": "Settings",
|
||||
"quitCoco": "Quit Coco",
|
||||
"checkUpdate": "Check for Updates"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user