feat: enable investigation mode

This commit is contained in:
Li Xin 2025-04-30 19:53:14 +08:00
parent 3ef36b95f6
commit 0a0f705aca
6 changed files with 104 additions and 23 deletions

View File

@ -13,8 +13,14 @@ import {
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import type { Option } from "~/core/messages"; import type { Option } from "~/core/messages";
import {
setEnableBackgroundInvestigation,
useSettingsStore,
} from "~/core/store";
import { cn } from "~/lib/utils"; import { cn } from "~/lib/utils";
import { Detective } from "../_icons/detective";
import { Tooltip } from "./tooltip"; import { Tooltip } from "./tooltip";
export function InputBox({ export function InputBox({
@ -37,6 +43,9 @@ export function InputBox({
const [message, setMessage] = useState(""); const [message, setMessage] = useState("");
const [imeStatus, setImeStatus] = useState<"active" | "inactive">("inactive"); const [imeStatus, setImeStatus] = useState<"active" | "inactive">("inactive");
const [indent, setIndent] = useState(0); const [indent, setIndent] = useState(0);
const backgroundInvestigation = useSettingsStore(
(state) => state.general.enableBackgroundInvestigation,
);
const textareaRef = useRef<HTMLTextAreaElement>(null); const textareaRef = useRef<HTMLTextAreaElement>(null);
const feedbackRef = useRef<HTMLDivElement>(null); const feedbackRef = useRef<HTMLDivElement>(null);
@ -137,7 +146,37 @@ export function InputBox({
/> />
</div> </div>
<div className="flex items-center px-4 py-2"> <div className="flex items-center px-4 py-2">
<div className="flex grow"></div> <div className="flex grow">
<Tooltip
className="max-w-60"
title={
<div>
<h3 className="mb-2 font-bold">
Investigation Mode: {backgroundInvestigation ? "On" : "Off"}
</h3>
<p>
When enabled, DeerFlow will perform a quick search before
planning. This is useful for researches related to ongoing
events and news.
</p>
</div>
}
>
<Button
className={cn(
"rounded-2xl",
backgroundInvestigation && "!border-brand !text-brand",
)}
variant="outline"
size="lg"
onClick={() =>
setEnableBackgroundInvestigation(!backgroundInvestigation)
}
>
<Detective /> Investigation
</Button>
</Tooltip>
</div>
<div className="flex shrink-0 items-center gap-2"> <div className="flex shrink-0 items-center gap-2">
<Tooltip title={responding ? "Stop" : "Send"}> <Tooltip title={responding ? "Stop" : "Send"}>
<Button <Button

View File

@ -0,0 +1,26 @@
export function Detective({ className }: { className?: string }) {
return (
<svg
className={className}
version="1.1"
width="800px"
height="800px"
viewBox="0 0 512 512"
>
<g fill="currentcolor">
<path
d="M392.692,257.322c-1.172-8.125-2.488-16.98-3.807-25.984c-5.856-39.012-12.59-81.688-14.86-87.832
c-4.318-11.715-18.371-44.723-68.217-25.984c-15.738,5.926-18.812,11.93-41.648,8.93c-17.273-2.27-28.326-15.59-52.336-24.668
c-49.844-18.883-71.584,11.711-75.902,23.422c-2.27,6.148-9.004,67.121-14.86,106.133c-1.39,8.86-2.633,17.566-3.804,25.621
c37.256,7.535,84.174,12.879,138.705,12.879C309.541,269.837,355.801,264.716,392.692,257.322z"
/>
<path
d="M443.707,306.509c-8.051-2.196-16.834-4.246-26.057-6.148c-1.83-0.805-3.66-1.535-5.49-2.27h-0.072
c-46.918,10.394-102.254,15.664-156.125,15.664c-53.652,0-108.768-5.27-155.541-15.516c-1.316,0.512-2.707,1.098-4.098,1.684
c-8.858,1.828-17.348,3.73-25.106,5.781l-0.148,0.074C27.008,317.49,0,333.372,0,350.939c0,36.012,114.549,65.289,256.035,65.289
c141.34,0,255.965-29.278,255.965-65.289C512,333.74,486.016,318.22,443.707,306.509z"
/>
</g>
</svg>
);
}

View File

@ -124,21 +124,20 @@ function Jumbotron() {
flickerChance={0.12} flickerChance={0.12}
/> />
<div className="relative z-10 flex flex-col items-center justify-center gap-12"> <div className="relative z-10 flex flex-col items-center justify-center gap-12">
<h1 className="text-center text-6xl font-bold"> <h1 className="text-center text-4xl font-bold md:text-6xl">
<span className="bg-gradient-to-r from-white via-gray-200 to-gray-400 bg-clip-text text-transparent"> <span className="bg-gradient-to-r from-white via-gray-200 to-gray-400 bg-clip-text text-transparent">
Deep Research{" "} Deep Research{" "}
</span> </span>
<AuroraText>at Your Fingertips</AuroraText> <AuroraText>at Your Fingertips</AuroraText>
</h1> </h1>
<p className="hidden max-w-4xl text-center text-2xl font-light opacity-75 md:block"> <p className="max-w-4xl p-2 text-center text-sm font-light opacity-80 md:text-2xl">
Discover the revolutionary Multi-Agent Research Assistant that Meet <span className="font-medium">DeerFlow</span>, your ultimate Deep
empowers you to dive deeper and wider into any subject. Equipped with Research assistant. With powerful tools like search engines, web
the powerful tools like search engines, crawlers, Python, and MCP crawlers, Python and MCP services, it provides instant insights,
services, DeerFlow provides instant insights, in-depth reports and comprehensive reports, or even captivating podcasts.
even captivating podcasts.
</p> </p>
<div className="flex gap-6"> <div className="flex gap-6">
<Button className="w-42 text-lg" size="lg" asChild> <Button className="hidden text-lg md:flex md:w-42" size="lg" asChild>
<Link href="/chat"> <Link href="/chat">
Get Started <ChevronRight /> Get Started <ChevronRight />
</Link> </Link>
@ -211,7 +210,7 @@ const caseStudies = [
function CaseStudySection() { function CaseStudySection() {
return ( return (
<section className="relative container flex flex-col items-center justify-center"> <section className="relative container hidden flex-col items-center justify-center md:flex">
<SectionHeader <SectionHeader
title="Case Studies" title="Case Studies"
description="See DeerFlow in action through replays." description="See DeerFlow in action through replays."

View File

@ -17,6 +17,7 @@ export async function* chatStream(
max_plan_iterations: number; max_plan_iterations: number;
max_step_num: number; max_step_num: number;
interrupt_feedback?: string; interrupt_feedback?: string;
enable_background_investigation: boolean;
mcp_settings?: { mcp_settings?: {
servers: Record< servers: Record<
string, string,

View File

@ -10,6 +10,7 @@ const SETTINGS_KEY = "deerflow.settings";
const DEFAULT_SETTINGS: SettingsState = { const DEFAULT_SETTINGS: SettingsState = {
general: { general: {
autoAcceptedPlan: false, autoAcceptedPlan: false,
enableBackgroundInvestigation: false,
maxPlanIterations: 1, maxPlanIterations: 1,
maxStepNum: 3, maxStepNum: 3,
}, },
@ -21,6 +22,7 @@ const DEFAULT_SETTINGS: SettingsState = {
export type SettingsState = { export type SettingsState = {
general: { general: {
autoAcceptedPlan: boolean; autoAcceptedPlan: boolean;
enableBackgroundInvestigation: boolean;
maxPlanIterations: number; maxPlanIterations: number;
maxStepNum: number; maxStepNum: number;
}; };
@ -48,9 +50,10 @@ export const loadSettings = () => {
const json = localStorage.getItem(SETTINGS_KEY); const json = localStorage.getItem(SETTINGS_KEY);
if (json) { if (json) {
const settings = JSON.parse(json); const settings = JSON.parse(json);
for (const key in DEFAULT_SETTINGS) { for (const key in DEFAULT_SETTINGS.general) {
if (!(key in settings)) { if (!(key in settings.general)) {
settings[key] = DEFAULT_SETTINGS[key as keyof SettingsState]; settings.general[key as keyof SettingsState["general"]] =
DEFAULT_SETTINGS.general[key as keyof SettingsState["general"]];
} }
} }
@ -120,4 +123,13 @@ export const getChatStreamSettings = () => {
}; };
}; };
export function setEnableBackgroundInvestigation(value: boolean) {
useSettingsStore.setState((state) => ({
general: {
...state.general,
enableBackgroundInvestigation: value,
},
}));
saveSettings();
}
loadSettings(); loadSettings();

View File

@ -50,7 +50,9 @@ export const useStore = create<{
})); }));
}, },
updateMessage(message: Message) { updateMessage(message: Message) {
set(state => ({ messages: new Map(state.messages).set(message.id, message) })); set((state) => ({
messages: new Map(state.messages).set(message.id, message),
}));
}, },
updateMessages(messages: Message[]) { updateMessages(messages: Message[]) {
set((state) => { set((state) => {
@ -67,7 +69,7 @@ export const useStore = create<{
}, },
setOngoingResearch(researchId: string | null) { setOngoingResearch(researchId: string | null) {
set({ ongoingResearchId: researchId }); set({ ongoingResearchId: researchId });
} },
})); }));
export async function sendMessage( export async function sendMessage(
@ -96,6 +98,8 @@ export async function sendMessage(
thread_id: THREAD_ID, thread_id: THREAD_ID,
interrupt_feedback: interruptFeedback, interrupt_feedback: interruptFeedback,
auto_accepted_plan: settings.autoAcceptedPlan, auto_accepted_plan: settings.autoAcceptedPlan,
enable_background_investigation:
settings.enableBackgroundInvestigation ?? true,
max_plan_iterations: settings.maxPlanIterations, max_plan_iterations: settings.maxPlanIterations,
max_step_num: settings.maxStepNum, max_step_num: settings.maxStepNum,
mcp_settings: settings.mcpSettings, mcp_settings: settings.mcpSettings,