mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-05-20 18:03:57 +00:00
Merge f8c4f240c3 into b69ca7ad97
This commit is contained in:
commit
4bdffabaed
7 changed files with 70 additions and 46 deletions
25
frontend/src/app/landing/page.tsx
Normal file
25
frontend/src/app/landing/page.tsx
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { Footer } from "@/components/landing/footer";
|
||||
import { Header } from "@/components/landing/header";
|
||||
import { Hero } from "@/components/landing/hero";
|
||||
import { CaseStudySection } from "@/components/landing/sections/case-study-section";
|
||||
import { CommunitySection } from "@/components/landing/sections/community-section";
|
||||
import { SandboxSection } from "@/components/landing/sections/sandbox-section";
|
||||
import { SkillsSection } from "@/components/landing/sections/skills-section";
|
||||
import { WhatsNewSection } from "@/components/landing/sections/whats-new-section";
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<div className="min-h-screen w-full bg-[#0a0a0a]">
|
||||
<Header />
|
||||
<main className="flex w-full flex-col">
|
||||
<Hero />
|
||||
<CaseStudySection />
|
||||
<SkillsSection />
|
||||
<SandboxSection />
|
||||
<WhatsNewSection />
|
||||
<CommunitySection />
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ export default async function RootLayout({
|
|||
const locale = await detectLocaleServer();
|
||||
return (
|
||||
<html lang={locale} suppressContentEditableWarning suppressHydrationWarning>
|
||||
<body>
|
||||
<body suppressHydrationWarning>
|
||||
<ThemeProvider attribute="class" enableSystem disableTransitionOnChange>
|
||||
<I18nProvider initialLocale={locale}>{children}</I18nProvider>
|
||||
</ThemeProvider>
|
||||
|
|
|
|||
|
|
@ -1,25 +1,5 @@
|
|||
import { Footer } from "@/components/landing/footer";
|
||||
import { Header } from "@/components/landing/header";
|
||||
import { Hero } from "@/components/landing/hero";
|
||||
import { CaseStudySection } from "@/components/landing/sections/case-study-section";
|
||||
import { CommunitySection } from "@/components/landing/sections/community-section";
|
||||
import { SandboxSection } from "@/components/landing/sections/sandbox-section";
|
||||
import { SkillsSection } from "@/components/landing/sections/skills-section";
|
||||
import { WhatsNewSection } from "@/components/landing/sections/whats-new-section";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<div className="min-h-screen w-full bg-[#0a0a0a]">
|
||||
<Header />
|
||||
<main className="flex w-full flex-col">
|
||||
<Hero />
|
||||
<CaseStudySection />
|
||||
<SkillsSection />
|
||||
<SandboxSection />
|
||||
<WhatsNewSection />
|
||||
<CommunitySection />
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
export default function HomePage() {
|
||||
redirect("/workspace");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -335,7 +335,9 @@ export default function Galaxy({
|
|||
ctn.removeEventListener("mousemove", handleMouseMove);
|
||||
ctn.removeEventListener("mouseleave", handleMouseLeave);
|
||||
}
|
||||
ctn.removeChild(gl.canvas);
|
||||
if (gl.canvas.parentNode === ctn) {
|
||||
ctn.removeChild(gl.canvas);
|
||||
}
|
||||
gl.getExtension("WEBGL_lose_context")?.loseContext();
|
||||
};
|
||||
}, [
|
||||
|
|
|
|||
|
|
@ -130,7 +130,9 @@ const ParticleCard: React.FC<{
|
|||
duration: 0.3,
|
||||
ease: "back.in(1.7)",
|
||||
onComplete: () => {
|
||||
particle.parentNode?.removeChild(particle);
|
||||
if (particle.parentNode) {
|
||||
particle.parentNode.removeChild(particle);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
@ -482,7 +484,9 @@ const GlobalSpotlight: React.FC<{
|
|||
return () => {
|
||||
document.removeEventListener("mousemove", handleMouseMove);
|
||||
document.removeEventListener("mouseleave", handleMouseLeave);
|
||||
spotlightRef.current?.parentNode?.removeChild(spotlightRef.current);
|
||||
if (spotlightRef.current?.parentNode) {
|
||||
spotlightRef.current.parentNode.removeChild(spotlightRef.current);
|
||||
}
|
||||
};
|
||||
}, [gridRef, disableAnimations, enabled, spotlightRadius, glowColor]);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,17 +40,28 @@ export function getMessageGroups(messages: Message[]): MessageGroup[] {
|
|||
|
||||
const groups: MessageGroup[] = [];
|
||||
|
||||
// Returns the last group if it can still accept tool messages
|
||||
// (i.e. it's an in-flight processing group, not a terminal human/assistant group).
|
||||
// Returns the nearest prior group that can still accept tool messages.
|
||||
// This intentionally scans backwards instead of only checking the last group,
|
||||
// because an AI message can now render both:
|
||||
// 1. an in-flight processing group for tool calls, and
|
||||
// 2. a normal assistant bubble for user-visible text.
|
||||
// In that case, the assistant bubble is appended after the processing group,
|
||||
// and later tool messages still belong to that earlier processing group.
|
||||
function lastOpenGroup() {
|
||||
const last = groups[groups.length - 1];
|
||||
if (
|
||||
last &&
|
||||
last.type !== "human" &&
|
||||
last.type !== "assistant" &&
|
||||
last.type !== "assistant:clarification"
|
||||
) {
|
||||
return last;
|
||||
for (let i = groups.length - 1; i >= 0; i -= 1) {
|
||||
const group = groups[i];
|
||||
if (!group) {
|
||||
continue;
|
||||
}
|
||||
if (group.type === "human") {
|
||||
return null;
|
||||
}
|
||||
if (
|
||||
group.type !== "assistant" &&
|
||||
group.type !== "assistant:clarification"
|
||||
) {
|
||||
return group;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -79,11 +90,6 @@ export function getMessageGroups(messages: Message[]): MessageGroup[] {
|
|||
const open = lastOpenGroup();
|
||||
if (open) {
|
||||
open.messages.push(message);
|
||||
} else {
|
||||
console.error(
|
||||
"Unexpected tool message outside a processing group",
|
||||
message,
|
||||
);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
|
@ -116,9 +122,14 @@ export function getMessageGroups(messages: Message[]): MessageGroup[] {
|
|||
}
|
||||
}
|
||||
|
||||
// Not an else-if: a message with reasoning + content (but no tool calls) goes
|
||||
// into the processing group above AND gets its own assistant bubble here.
|
||||
if (hasContent(message) && !hasToolCalls(message)) {
|
||||
// Not an else-if: intermediate assistant messages can contain both
|
||||
// user-facing text and tool calls. We still want to show that text as a
|
||||
// normal assistant bubble instead of rendering only the tool timeline.
|
||||
if (
|
||||
hasContent(message) &&
|
||||
!hasPresentFiles(message) &&
|
||||
!hasSubagent(message)
|
||||
) {
|
||||
groups.push({ id: message.id, type: "assistant", messages: [message] });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,9 @@ export function downloadAsFile(
|
|||
a.download = filename;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
if (a.parentNode === document.body) {
|
||||
document.body.removeChild(a);
|
||||
}
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue