diff --git a/frontend/src/app/mock/api/threads/[thread_id]/artifacts/[[...artifact_path]]/route.ts b/frontend/src/app/mock/api/threads/[thread_id]/artifacts/[[...artifact_path]]/route.ts index 78447d2..7c4d55d 100644 --- a/frontend/src/app/mock/api/threads/[thread_id]/artifacts/[[...artifact_path]]/route.ts +++ b/frontend/src/app/mock/api/threads/[thread_id]/artifacts/[[...artifact_path]]/route.ts @@ -34,6 +34,14 @@ export async function GET( headers, }); } + if (artifactPath.endsWith(".mp4")) { + return new Response(fs.readFileSync(artifactPath), { + status: 200, + headers: { + "Content-Type": "video/mp4", + }, + }); + } return new Response(fs.readFileSync(artifactPath), { status: 200 }); } } diff --git a/frontend/src/app/workspace/chats/[thread_id]/page.tsx b/frontend/src/app/workspace/chats/[thread_id]/page.tsx index 32c038a..5fda9f2 100644 --- a/frontend/src/app/workspace/chats/[thread_id]/page.tsx +++ b/frontend/src/app/workspace/chats/[thread_id]/page.tsx @@ -93,6 +93,13 @@ export default function ChatPage() { thread.values.artifacts, ]); + const artifactPanelOpen = useMemo(() => { + if (env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true") { + return artifactsOpen && artifacts?.length > 0; + } + return artifactsOpen; + }, [artifactsOpen, artifacts]); + const [todoListCollapsed, setTodoListCollapsed] = useState( env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY !== "true", ); @@ -119,8 +126,8 @@ export default function ChatPage() { 0 ? 46 : 100} - minSize={artifactsOpen && artifacts?.length > 0 ? 30 : 100} + defaultSize={artifactPanelOpen ? 46 : 100} + minSize={artifactPanelOpen ? 30 : 100} >
0 && - "pointer-events-none opacity-0", + !artifactPanelOpen && "pointer-events-none opacity-0", )} /> 0 ? 64 : 0} + defaultSize={artifactPanelOpen ? 64 : 0} minSize={0} - maxSize={artifactsOpen && artifacts?.length > 0 ? undefined : 0} + maxSize={artifactPanelOpen ? undefined : 0} >
0 - ? "translate-x-0" - : "translate-x-full", + artifactPanelOpen ? "translate-x-0" : "translate-x-full", )} > {selectedArtifact ? ( diff --git a/frontend/src/components/landing/sections/case-study-section.tsx b/frontend/src/components/landing/sections/case-study-section.tsx index d3f6464..9a1fd51 100644 --- a/frontend/src/components/landing/sections/case-study-section.tsx +++ b/frontend/src/components/landing/sections/case-study-section.tsx @@ -1,40 +1,48 @@ -import { SparklesIcon } from "lucide-react"; +import Link from "next/link"; -import SpotlightCard from "@/components/ui/spotlight-card"; +import { Card } from "@/components/ui/card"; +import { pathOfThread } from "@/core/threads/utils"; +import { cn } from "@/lib/utils"; import { Section } from "../section"; export function CaseStudySection({ className }: { className?: string }) { const caseStudies = [ { - title: "2025 Survey", + threadId: "7cfa5f8f-a2f8-47ad-acbd-da7137baf990", + title: "Forecast 2026 Agent Trends and Opportunities", description: - "A 12,000-word research report analyzing 47 papers on brain-inspired chips, covering Intel Loihi 2, IBM NorthPole, and SynSense's edge AI solutions.", + "Create a webpage with a Deep Research report forecasting the agent technology trends and opportunities in 2026.", }, { - title: "Indie Hacker's SaaS Landing Page", + threadId: "4f3e55ee-f853-43db-bfb3-7d1a411f03cb", + title: 'Generate a Video Based On the Novel "Pride and Prejudice"', description: - "A fully responsive landing page with hero section, pricing table, testimonials, and Stripe integration — shipped in one conversation.", + 'Search the specific scene from the novel "Pride and Prejudice", then generate a video as well as a reference image based on the scenes.', }, { - title: "Transformer Architecture Explained", + threadId: "21cfea46-34bd-4aa6-9e1f-3009452fbeb9", + title: "Doraemon Explains the MOE Architecture", description: - "A 25-slide presentation breaking down self-attention, positional encoding, and KV-cache with hand-drawn style diagrams for a university lecture.", + "Generate a Doraemon comic strip explaining the MOE architecture to the teenagers who are interested in AI.", }, { - title: "DeerDeer Explains RAG", + threadId: "ad76c455-5bf9-4335-8517-fc03834ab828", + title: "An Exploratory Data Analysis of the Titanic Dataset", description: - "A series of 12 illustrations featuring a curious deer mascot explaining Retrieval-Augmented Generation through a library adventure story.", + "Explore the Titanic dataset and identify the key factors that influenced survival rates with visualizations and insights.", }, { - title: "AI Weekly: Your Tech Podcast", + threadId: "d3e5adaf-084c-4dd5-9d29-94f1d6bccd98", + title: "Watch Y Combinator's Video then Conduct a Deep Research", description: - "A 20-minute podcast episode where two AI hosts debate whether AI agents will replace traditional SaaS, based on 5 articles you provided.", + "Watch the given Y Combinator's YouTube video and conduct a deep research on the YC's tips for technical startup founders.", }, { - title: "How Diffusion Models Work", + threadId: "3823e443-4e2b-4679-b496-a9506eae462b", + title: "Collect and Summarize Dr. Fei Fei Li's Podcasts", description: - "A 3-minute animated explainer video visualizing the denoising process, from pure noise to a generated image, with voiceover narration.", + "Collect all the podcast appearances of Dr. Fei Fei Li in the last 6 months, then summarize them into a comprehensive report.", }, ]; return ( @@ -43,23 +51,46 @@ export function CaseStudySection({ className }: { className?: string }) { title="Case Studies" subtitle="See how DeerFlow is used in the wild" > -
+
{caseStudies.map((caseStudy) => ( - -
-
-
- -
-
-

{caseStudy.title}

-

- {caseStudy.description} -

+ + +
+
+
+
+

+ {caseStudy.title} +

+

+ {caseStudy.description} +

+
-
- + + ))}
diff --git a/frontend/src/components/ui/spotlight-card.tsx b/frontend/src/components/ui/spotlight-card.tsx index 85b780c..bc183ab 100644 --- a/frontend/src/components/ui/spotlight-card.tsx +++ b/frontend/src/components/ui/spotlight-card.tsx @@ -11,9 +11,11 @@ interface Position { interface SpotlightCardProps extends React.PropsWithChildren { className?: string; spotlightColor?: `rgba(${number}, ${number}, ${number}, ${number})`; + style?: React.CSSProperties; } const SpotlightCard: React.FC = ({ + style, children, className = "", spotlightColor = "rgba(255, 255, 255, 0.25)", @@ -37,6 +39,7 @@ const SpotlightCard: React.FC = ({ ref={divRef} onMouseMove={handleMouseMove} className={`card-spotlight ${className}`} + style={style} > {children}