mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-03 06:12:14 +08:00
refactor: refine folder structure and rename
This commit is contained in:
@@ -17,8 +17,12 @@ import {
|
||||
WorkspaceFooter,
|
||||
} from "@/components/workspace/workspace-container";
|
||||
import { getLangGraphClient } from "@/core/api";
|
||||
import type { MessageThread, MessageThreadState } from "@/core/thread";
|
||||
import { titleOfThread } from "@/core/thread/utils";
|
||||
import type {
|
||||
AgentThread,
|
||||
AgentThreadContext,
|
||||
AgentThreadState,
|
||||
} from "@/core/threads";
|
||||
import { titleOfThread } from "@/core/threads/utils";
|
||||
import { uuid } from "@/core/utils/uuid";
|
||||
|
||||
const langGraphClient = getLangGraphClient();
|
||||
@@ -32,6 +36,11 @@ export default function ChatPage() {
|
||||
[threadIdFromPath],
|
||||
);
|
||||
const [threadId, setThreadId] = useState<string | null>(null);
|
||||
const [threadContext, setThreadContext] = useState<AgentThreadContext>({
|
||||
thread_id: "",
|
||||
model: "deepseek-v3.2",
|
||||
thinking_enabled: true,
|
||||
});
|
||||
useEffect(() => {
|
||||
if (threadIdFromPath !== "new") {
|
||||
setThreadId(threadIdFromPath);
|
||||
@@ -39,7 +48,7 @@ export default function ChatPage() {
|
||||
setThreadId(uuid());
|
||||
}
|
||||
}, [threadIdFromPath]);
|
||||
const thread = useStream<MessageThreadState>({
|
||||
const thread = useStream<AgentThreadState>({
|
||||
client: langGraphClient,
|
||||
assistantId: "lead_agent",
|
||||
threadId: !isNewThread ? threadId : undefined,
|
||||
@@ -74,15 +83,14 @@ export default function ChatPage() {
|
||||
streamSubgraphs: true,
|
||||
streamResumable: true,
|
||||
context: {
|
||||
...threadContext,
|
||||
thread_id: threadId!,
|
||||
model: "deepseek-v3.2",
|
||||
thinking_enabled: true,
|
||||
},
|
||||
},
|
||||
);
|
||||
void queryClient.invalidateQueries({ queryKey: ["threads", "search"] });
|
||||
},
|
||||
[isNewThread, queryClient, router, thread, threadId],
|
||||
[isNewThread, queryClient, router, thread, threadContext, threadId],
|
||||
);
|
||||
const handleStop = useCallback(async () => {
|
||||
await thread.stop();
|
||||
@@ -93,7 +101,7 @@ export default function ChatPage() {
|
||||
<BreadcrumbItem className="hidden md:block">
|
||||
{isNewThread
|
||||
? "New"
|
||||
: titleOfThread(thread as unknown as MessageThread)}
|
||||
: titleOfThread(thread as unknown as AgentThread)}
|
||||
</BreadcrumbItem>
|
||||
</WorkspaceHeader>
|
||||
<WorkspaceBody>
|
||||
|
||||
@@ -4,13 +4,13 @@ import { useStream } from "@langchain/langgraph-sdk/react";
|
||||
import { useParams } from "next/navigation";
|
||||
|
||||
import { getLangGraphClient } from "@/core/api";
|
||||
import type { MessageThreadState } from "@/core/thread";
|
||||
import type { AgentThreadState } from "@/core/threads";
|
||||
|
||||
const apiClient = getLangGraphClient();
|
||||
|
||||
export default function TestPage() {
|
||||
const { thread_id: threadId } = useParams<{ thread_id: string }>();
|
||||
const thread = useStream<MessageThreadState>({
|
||||
const thread = useStream<AgentThreadState>({
|
||||
client: apiClient,
|
||||
assistantId: "lead_agent",
|
||||
threadId,
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import type { ChatStatus } from "ai";
|
||||
import { LightbulbIcon, LightbulbOffIcon } from "lucide-react";
|
||||
import { useCallback, type ComponentProps } from "react";
|
||||
|
||||
import {
|
||||
PromptInput,
|
||||
PromptInputBody,
|
||||
PromptInputButton,
|
||||
PromptInputFooter,
|
||||
PromptInputSubmit,
|
||||
PromptInputTextarea,
|
||||
@@ -11,6 +13,8 @@ import {
|
||||
} from "@/components/ai-elements/prompt-input";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { Tooltip } from "./tooltip";
|
||||
|
||||
export function InputBox({
|
||||
className,
|
||||
autoFocus,
|
||||
@@ -57,7 +61,13 @@ export function InputBox({
|
||||
/>
|
||||
</PromptInputBody>
|
||||
<PromptInputFooter className="flex">
|
||||
<div></div>
|
||||
<div>
|
||||
<Tooltip content="">
|
||||
<PromptInputButton>
|
||||
<LightbulbOffIcon className="size-4" />
|
||||
</PromptInputButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<PromptInputSubmit
|
||||
className="rounded-full"
|
||||
|
||||
@@ -21,14 +21,13 @@ import {
|
||||
ChainOfThoughtStep,
|
||||
} from "@/components/ai-elements/chain-of-thought";
|
||||
import { MessageResponse } from "@/components/ai-elements/message";
|
||||
import { useRehypeSplitWordsIntoSpans } from "@/core/rehype";
|
||||
import { extractTitleFromMarkdown } from "@/core/utils/markdown";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import {
|
||||
extractReasoningContentFromMessage,
|
||||
findToolCallResult,
|
||||
} from "./utils";
|
||||
} from "@/core/messages/utils";
|
||||
import { useRehypeSplitWordsIntoSpans } from "@/core/rehype";
|
||||
import { extractTitleFromMarkdown } from "@/core/utils/markdown";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export function MessageGroup({
|
||||
className,
|
||||
|
||||
@@ -6,11 +6,15 @@ import {
|
||||
MessageContent as AIElementMessageContent,
|
||||
MessageResponse as AIElementMessageResponse,
|
||||
} from "@/components/ai-elements/message";
|
||||
import {
|
||||
extractContentFromMessage,
|
||||
hasReasoning,
|
||||
hasToolCalls,
|
||||
} from "@/core/messages/utils";
|
||||
import { useRehypeSplitWordsIntoSpans } from "@/core/rehype";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { MessageGroup } from "./message-group";
|
||||
import { extractContentFromMessage, hasReasoning, hasToolCalls } from "./utils";
|
||||
|
||||
export function MessageListItem({
|
||||
className,
|
||||
|
||||
@@ -5,7 +5,8 @@ import {
|
||||
ConversationContent,
|
||||
ConversationScrollButton,
|
||||
} from "@/components/ai-elements/conversation";
|
||||
import type { MessageThreadState } from "@/core/thread";
|
||||
import { groupMessages, hasContent } from "@/core/messages/utils";
|
||||
import type { AgentThreadState } from "@/core/threads";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { StreamingIndicator } from "../streaming-indicator";
|
||||
@@ -13,14 +14,13 @@ import { StreamingIndicator } from "../streaming-indicator";
|
||||
import { MessageGroup } from "./message-group";
|
||||
import { MessageListItem } from "./message-list-item";
|
||||
import { MessageListSkeleton } from "./skeleton";
|
||||
import { groupMessages, hasContent } from "./utils";
|
||||
|
||||
export function MessageList({
|
||||
className,
|
||||
thread,
|
||||
}: {
|
||||
className?: string;
|
||||
thread: UseStream<MessageThreadState>;
|
||||
thread: UseStream<AgentThreadState>;
|
||||
}) {
|
||||
if (thread.isThreadLoading) {
|
||||
return <MessageListSkeleton />;
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
SidebarMenuItem,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { useDeleteThread, useThreads } from "@/core/api";
|
||||
import { pathOfThread, titleOfThread } from "@/core/thread/utils";
|
||||
import { pathOfThread, titleOfThread } from "@/core/threads/utils";
|
||||
|
||||
export function RecentChatList() {
|
||||
const router = useRouter();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ThreadsClient } from "@langchain/langgraph-sdk/client";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import type { MessageThread, MessageThreadState } from "../thread";
|
||||
import type { AgentThread, AgentThreadState } from "../threads";
|
||||
|
||||
import { getLangGraphClient } from "./client";
|
||||
|
||||
@@ -13,12 +13,12 @@ export function useThreads(
|
||||
},
|
||||
) {
|
||||
const langGraphClient = getLangGraphClient();
|
||||
return useQuery<MessageThread[]>({
|
||||
return useQuery<AgentThread[]>({
|
||||
queryKey: ["threads", "search", params],
|
||||
queryFn: async () => {
|
||||
const response =
|
||||
await langGraphClient.threads.search<MessageThreadState>(params);
|
||||
return response as MessageThread[];
|
||||
await langGraphClient.threads.search<AgentThreadState>(params);
|
||||
return response as AgentThread[];
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -36,7 +36,7 @@ export function useDeleteThread() {
|
||||
queryKey: ["threads", "search"],
|
||||
exact: false,
|
||||
},
|
||||
(oldData: Array<MessageThread>) => {
|
||||
(oldData: Array<AgentThread>) => {
|
||||
return oldData.filter((t) => t.thread_id !== threadId);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
import { type BaseMessage } from "@langchain/core/messages";
|
||||
import type { Thread } from "@langchain/langgraph-sdk";
|
||||
|
||||
export interface MessageThreadState extends Record<string, unknown> {
|
||||
messages: BaseMessage[];
|
||||
}
|
||||
|
||||
export interface MessageThread extends Thread<MessageThreadState> {}
|
||||
15
frontend/src/core/threads/types.ts
Normal file
15
frontend/src/core/threads/types.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { type BaseMessage } from "@langchain/core/messages";
|
||||
import type { Thread } from "@langchain/langgraph-sdk";
|
||||
|
||||
export interface AgentThreadState extends Record<string, unknown> {
|
||||
title: string;
|
||||
messages: BaseMessage[];
|
||||
}
|
||||
|
||||
export interface AgentThread extends Thread<AgentThreadState> {}
|
||||
|
||||
export interface AgentThreadContext extends Record<string, unknown> {
|
||||
thread_id: string;
|
||||
model: string;
|
||||
thinking_enabled: boolean;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { BaseMessage } from "@langchain/core/messages";
|
||||
|
||||
import type { MessageThread } from "./types";
|
||||
import type { AgentThread } from "./types";
|
||||
|
||||
export function pathOfThread(thread: MessageThread, includeAssistantId = true) {
|
||||
export function pathOfThread(thread: AgentThread, includeAssistantId = true) {
|
||||
if (includeAssistantId) {
|
||||
return `/workspace/chats/${thread.thread_id}`;
|
||||
}
|
||||
@@ -19,9 +19,9 @@ export function textOfMessage(message: BaseMessage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function titleOfThread(thread: MessageThread) {
|
||||
export function titleOfThread(thread: AgentThread) {
|
||||
if (thread.values && "title" in thread.values) {
|
||||
return thread.values.title as string;
|
||||
return thread.values.title;
|
||||
}
|
||||
return "Untitled";
|
||||
}
|
||||
Reference in New Issue
Block a user