mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-27 15:54:48 +08:00
fix: next server fetch error (#374)
This commit is contained in:
@@ -15,7 +15,7 @@ import { Tooltip } from "~/components/deer-flow/tooltip";
|
|||||||
import { BorderBeam } from "~/components/magicui/border-beam";
|
import { BorderBeam } from "~/components/magicui/border-beam";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { enhancePrompt } from "~/core/api";
|
import { enhancePrompt } from "~/core/api";
|
||||||
import { getConfig } from "~/core/api/config";
|
import { useConfig } from "~/core/api/hooks";
|
||||||
import type { Option, Resource } from "~/core/messages";
|
import type { Option, Resource } from "~/core/messages";
|
||||||
import {
|
import {
|
||||||
setEnableDeepThinking,
|
setEnableDeepThinking,
|
||||||
@@ -52,7 +52,7 @@ export function InputBox({
|
|||||||
const backgroundInvestigation = useSettingsStore(
|
const backgroundInvestigation = useSettingsStore(
|
||||||
(state) => state.general.enableBackgroundInvestigation,
|
(state) => state.general.enableBackgroundInvestigation,
|
||||||
);
|
);
|
||||||
const reasoningModel = useMemo(() => getConfig().models.reasoning?.[0], []);
|
const { config, loading } = useConfig();
|
||||||
const reportStyle = useSettingsStore((state) => state.general.reportStyle);
|
const reportStyle = useSettingsStore((state) => state.general.reportStyle);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const inputRef = useRef<MessageInputRef>(null);
|
const inputRef = useRef<MessageInputRef>(null);
|
||||||
@@ -203,13 +203,15 @@ export function InputBox({
|
|||||||
isEnhanceAnimating && "transition-all duration-500",
|
isEnhanceAnimating && "transition-all duration-500",
|
||||||
)}
|
)}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
|
loading={loading}
|
||||||
|
config={config}
|
||||||
onEnter={handleSendMessage}
|
onEnter={handleSendMessage}
|
||||||
onChange={setCurrentPrompt}
|
onChange={setCurrentPrompt}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center px-4 py-2">
|
<div className="flex items-center px-4 py-2">
|
||||||
<div className="flex grow gap-2">
|
<div className="flex grow gap-2">
|
||||||
{reasoningModel && (
|
{config?.models.reasoning?.[0] && (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
className="max-w-60"
|
className="max-w-60"
|
||||||
title={
|
title={
|
||||||
@@ -219,7 +221,8 @@ export function InputBox({
|
|||||||
</h3>
|
</h3>
|
||||||
<p>
|
<p>
|
||||||
When enabled, DeerFlow will use reasoning model (
|
When enabled, DeerFlow will use reasoning model (
|
||||||
{reasoningModel}) to generate more thoughtful plans.
|
{config.models.reasoning?.[0]}) to generate more thoughtful
|
||||||
|
plans.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { Geist } from "next/font/google";
|
|||||||
import Script from "next/script";
|
import Script from "next/script";
|
||||||
|
|
||||||
import { ThemeProviderWrapper } from "~/components/deer-flow/theme-provider-wrapper";
|
import { ThemeProviderWrapper } from "~/components/deer-flow/theme-provider-wrapper";
|
||||||
import { loadConfig } from "~/core/api/config";
|
|
||||||
import { env } from "~/env";
|
import { env } from "~/env";
|
||||||
|
|
||||||
import { Toaster } from "../components/deer-flow/toaster";
|
import { Toaster } from "../components/deer-flow/toaster";
|
||||||
@@ -28,11 +27,9 @@ const geist = Geist({
|
|||||||
export default async function RootLayout({
|
export default async function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: Readonly<{ children: React.ReactNode }>) {
|
}: Readonly<{ children: React.ReactNode }>) {
|
||||||
const conf = await loadConfig();
|
|
||||||
return (
|
return (
|
||||||
<html lang="en" className={`${geist.variable}`} suppressHydrationWarning>
|
<html lang="en" className={`${geist.variable}`} suppressHydrationWarning>
|
||||||
<head>
|
<head>
|
||||||
<script>{`window.__deerflowConfig = ${JSON.stringify(conf)}`}</script>
|
|
||||||
{/* Define isSpace function globally to fix markdown-it issues with Next.js + Turbopack
|
{/* Define isSpace function globally to fix markdown-it issues with Next.js + Turbopack
|
||||||
https://github.com/markdown-it/markdown-it/issues/1082#issuecomment-2749656365 */}
|
https://github.com/markdown-it/markdown-it/issues/1082#issuecomment-2749656365 */}
|
||||||
<Script id="markdown-it-fix" strategy="beforeInteractive">
|
<Script id="markdown-it-fix" strategy="beforeInteractive">
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ import "~/styles/prosemirror.css";
|
|||||||
import { resourceSuggestion } from "./resource-suggestion";
|
import { resourceSuggestion } from "./resource-suggestion";
|
||||||
import React, { forwardRef, useEffect, useMemo, useRef } from "react";
|
import React, { forwardRef, useEffect, useMemo, useRef } from "react";
|
||||||
import type { Resource } from "~/core/messages";
|
import type { Resource } from "~/core/messages";
|
||||||
import { useRAGProvider } from "~/core/api/hooks";
|
import { useConfig } from "~/core/api/hooks";
|
||||||
import { LoadingOutlined } from "@ant-design/icons";
|
import { LoadingOutlined } from "@ant-design/icons";
|
||||||
|
import type { DeerFlowConfig } from "~/core/config";
|
||||||
|
|
||||||
export interface MessageInputRef {
|
export interface MessageInputRef {
|
||||||
focus: () => void;
|
focus: () => void;
|
||||||
@@ -32,6 +33,8 @@ export interface MessageInputRef {
|
|||||||
export interface MessageInputProps {
|
export interface MessageInputProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
|
loading?: boolean;
|
||||||
|
config?: DeerFlowConfig | null;
|
||||||
onChange?: (markdown: string) => void;
|
onChange?: (markdown: string) => void;
|
||||||
onEnter?: (message: string, resources: Array<Resource>) => void;
|
onEnter?: (message: string, resources: Array<Resource>) => void;
|
||||||
}
|
}
|
||||||
@@ -75,7 +78,10 @@ function formatItem(item: JSONContent): {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(
|
const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(
|
||||||
({ className, onChange, onEnter }: MessageInputProps, ref) => {
|
(
|
||||||
|
{ className, loading, config, onChange, onEnter }: MessageInputProps,
|
||||||
|
ref,
|
||||||
|
) => {
|
||||||
const editorRef = useRef<Editor>(null);
|
const editorRef = useRef<Editor>(null);
|
||||||
const handleEnterRef = useRef<
|
const handleEnterRef = useRef<
|
||||||
((message: string, resources: Array<Resource>) => void) | undefined
|
((message: string, resources: Array<Resource>) => void) | undefined
|
||||||
@@ -115,8 +121,6 @@ const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(
|
|||||||
handleEnterRef.current = onEnter;
|
handleEnterRef.current = onEnter;
|
||||||
}, [onEnter]);
|
}, [onEnter]);
|
||||||
|
|
||||||
const { provider, loading } = useRAGProvider();
|
|
||||||
|
|
||||||
const extensions = useMemo(() => {
|
const extensions = useMemo(() => {
|
||||||
const extensions = [
|
const extensions = [
|
||||||
StarterKit,
|
StarterKit,
|
||||||
@@ -132,7 +136,7 @@ const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(
|
|||||||
}),
|
}),
|
||||||
Placeholder.configure({
|
Placeholder.configure({
|
||||||
showOnlyCurrent: false,
|
showOnlyCurrent: false,
|
||||||
placeholder: provider
|
placeholder: config?.rag.provider
|
||||||
? "What can I do for you? \nYou may refer to RAG resources by using @."
|
? "What can I do for you? \nYou may refer to RAG resources by using @."
|
||||||
: "What can I do for you?",
|
: "What can I do for you?",
|
||||||
emptyEditorClass: "placeholder",
|
emptyEditorClass: "placeholder",
|
||||||
@@ -154,7 +158,7 @@ const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
if (provider) {
|
if (config?.rag.provider) {
|
||||||
extensions.push(
|
extensions.push(
|
||||||
Mention.configure({
|
Mention.configure({
|
||||||
HTMLAttributes: {
|
HTMLAttributes: {
|
||||||
@@ -165,7 +169,7 @@ const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
return extensions;
|
return extensions;
|
||||||
}, [provider]);
|
}, [config]);
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
import { type DeerFlowConfig } from "../config/types";
|
|
||||||
|
|
||||||
import { resolveServiceURL } from "./resolve-service-url";
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface Window {
|
|
||||||
__deerflowConfig: DeerFlowConfig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function loadConfig() {
|
|
||||||
const res = await fetch(resolveServiceURL("./config"));
|
|
||||||
const config = await res.json();
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getConfig(): DeerFlowConfig {
|
|
||||||
if (
|
|
||||||
typeof window === "undefined" ||
|
|
||||||
typeof window.__deerflowConfig === "undefined"
|
|
||||||
) {
|
|
||||||
throw new Error("Config not loaded");
|
|
||||||
}
|
|
||||||
return window.__deerflowConfig;
|
|
||||||
}
|
|
||||||
@@ -5,10 +5,11 @@ import { useEffect, useRef, useState } from "react";
|
|||||||
|
|
||||||
import { env } from "~/env";
|
import { env } from "~/env";
|
||||||
|
|
||||||
|
import type { DeerFlowConfig } from "../config";
|
||||||
import { useReplay } from "../replay";
|
import { useReplay } from "../replay";
|
||||||
|
|
||||||
import { fetchReplayTitle } from "./chat";
|
import { fetchReplayTitle } from "./chat";
|
||||||
import { getConfig } from "./config";
|
import { resolveServiceURL } from "./resolve-service-url";
|
||||||
|
|
||||||
export function useReplayMetadata() {
|
export function useReplayMetadata() {
|
||||||
const { isReplay } = useReplay();
|
const { isReplay } = useReplay();
|
||||||
@@ -43,18 +44,30 @@ export function useReplayMetadata() {
|
|||||||
return { title, isLoading, hasError: error };
|
return { title, isLoading, hasError: error };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useRAGProvider() {
|
export function useConfig(): {
|
||||||
|
config: DeerFlowConfig | null;
|
||||||
|
loading: boolean;
|
||||||
|
} {
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [provider, setProvider] = useState<string | null>(null);
|
const [config, setConfig] = useState<DeerFlowConfig | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY) {
|
if (env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setProvider(getConfig().rag.provider);
|
fetch(resolveServiceURL("./config"))
|
||||||
setLoading(false);
|
.then((res) => res.json())
|
||||||
|
.then((config) => {
|
||||||
|
setConfig(config);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error("Failed to fetch config", err);
|
||||||
|
setConfig(null);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return { provider, loading };
|
return { config, loading };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user