Compare commits
1 Commits
main
...
save_threa
| Author | SHA1 | Date | |
|---|---|---|---|
| 135ea06ac1 |
@@ -1,6 +1,6 @@
|
||||
# LangGraph Configuration
|
||||
NEXT_PUBLIC_API_URL=http://localhost:2024
|
||||
NEXT_PUBLIC_ASSISTANT_ID=agent
|
||||
NEXT_PUBLIC_ASSISTANT_ID=my_agent
|
||||
# Do NOT prefix this with "NEXT_PUBLIC_" as we do not want this exposed in the client.
|
||||
LANGSMITH_API_KEY=
|
||||
|
||||
|
||||
10805
package-lock.json
generated
Normal file
10805
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@ import {
|
||||
XIcon,
|
||||
Plus,
|
||||
CircleX,
|
||||
Download
|
||||
} from "lucide-react";
|
||||
import { useQueryState, parseAsBoolean } from "nuqs";
|
||||
import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
||||
@@ -143,6 +144,59 @@ export function Thread() {
|
||||
const messages = stream.messages;
|
||||
const isLoading = stream.isLoading;
|
||||
|
||||
// 保存聊天记录功能
|
||||
const saveChatHistory = () => {
|
||||
if (!messages.length) {
|
||||
toast.info("没有可保存的聊天记录");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 准备聊天记录数据
|
||||
const chatData = {
|
||||
threadId: threadId || "new_thread",
|
||||
timestamp: new Date().toISOString(),
|
||||
messages: messages.map(msg => {
|
||||
// 安全处理消息内容
|
||||
let content = "";
|
||||
try {
|
||||
if (typeof msg.content === 'string') {
|
||||
content = msg.content;
|
||||
} else if (msg.content) {
|
||||
// 直接将非字符串内容转换为字符串
|
||||
content = JSON.stringify(msg.content, null, 2);
|
||||
}
|
||||
} catch (e) {
|
||||
content = String(msg.content || "");
|
||||
}
|
||||
|
||||
return {
|
||||
type: msg.type || "unknown",
|
||||
content: content,
|
||||
id: msg.id || uuidv4(),
|
||||
createdAt: new Date().toISOString()
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
||||
// 创建Blob并下载
|
||||
const blob = new Blob([JSON.stringify(chatData, null, 2)], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `chat_history_${new Date().toISOString().slice(0, 10)}_${threadId || 'new'}.json`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
|
||||
toast.success("聊天记录已保存");
|
||||
} catch (error) {
|
||||
console.error("保存聊天记录失败:", error);
|
||||
toast.error("保存聊天记录失败,请重试");
|
||||
}
|
||||
};
|
||||
|
||||
const lastError = useRef<string | undefined>(undefined);
|
||||
|
||||
const setThreadId = (id: string | null) => {
|
||||
@@ -371,6 +425,16 @@ export function Thread() {
|
||||
<div className="flex items-center">
|
||||
<OpenGitHubRepo />
|
||||
</div>
|
||||
<TooltipIconButton
|
||||
size="lg"
|
||||
className="p-4"
|
||||
tooltip="Save chat history"
|
||||
variant="ghost"
|
||||
onClick={saveChatHistory}
|
||||
disabled={messages.length === 0}
|
||||
>
|
||||
<Download className="size-5" />
|
||||
</TooltipIconButton>
|
||||
<TooltipIconButton
|
||||
size="lg"
|
||||
className="p-4"
|
||||
|
||||
@@ -127,7 +127,7 @@ const StreamSession = ({
|
||||
|
||||
// Default values for the form
|
||||
const DEFAULT_API_URL = "http://localhost:2024";
|
||||
const DEFAULT_ASSISTANT_ID = "agent";
|
||||
const DEFAULT_ASSISTANT_ID = "my_agent";
|
||||
|
||||
export const StreamProvider: React.FC<{ children: ReactNode }> = ({
|
||||
children,
|
||||
|
||||
Reference in New Issue
Block a user