164 lines
5.2 KiB
TypeScript
164 lines
5.2 KiB
TypeScript
import { cookies } from "next/headers";
|
|
import { redirect } from "next/navigation";
|
|
import { Suspense } from "react";
|
|
import { Chat } from "@/components/chat";
|
|
import { DataStreamHandler } from "@/components/data-stream-handler";
|
|
import { LovartHome } from "@/components/home/lovart-home";
|
|
import { generateUUID } from "@/lib/utils";
|
|
import { auth } from "../(auth)/auth";
|
|
import {
|
|
getDefaultAiModel,
|
|
getEnabledAiModelsWithProvider,
|
|
getUserById,
|
|
getSiteSettings,
|
|
getSystemSetting,
|
|
} from "@/lib/db/queries";
|
|
import { isAiModelAgentAuto } from "@/lib/db/ai-model-flags";
|
|
import { isVideoModelDescriptor } from "@/lib/ai/model-classification";
|
|
|
|
function isNanoBananaProModel(model: { displayName?: string | null; modelId?: string | null }) {
|
|
const displayName = String(model.displayName || "").toLowerCase();
|
|
const modelId = String(model.modelId || "").toLowerCase();
|
|
return (
|
|
displayName.includes("nano banana pro") ||
|
|
displayName.includes("nano-banana-pro") ||
|
|
modelId.includes("nano-banana-pro") ||
|
|
modelId.includes("nano_banana_pro") ||
|
|
modelId.includes("nano-banana")
|
|
);
|
|
}
|
|
|
|
export default function Page() {
|
|
return (
|
|
<Suspense fallback={<div className="flex h-dvh" />}>
|
|
<NewChatPage />
|
|
</Suspense>
|
|
);
|
|
}
|
|
|
|
async function NewChatPage() {
|
|
const id = generateUUID();
|
|
|
|
const [session, cookieStore, siteSettings, homeVariantSetting, surpriseCategoriesSetting] =
|
|
await Promise.all([
|
|
auth(),
|
|
cookies(),
|
|
getSiteSettings(),
|
|
getSystemSetting({ key: "home_variant" }).catch(() => undefined),
|
|
getSystemSetting({ key: "home_surprise_categories" }).catch(() => undefined),
|
|
]);
|
|
|
|
const homeVariant = homeVariantSetting?.value === "lovart" ? "lovart" : "classic";
|
|
const surpriseCategories = Array.isArray(surpriseCategoriesSetting?.value)
|
|
? surpriseCategoriesSetting?.value
|
|
.map((item: unknown) => String(item || "").trim())
|
|
.filter(Boolean)
|
|
: ["全部", "精选"];
|
|
|
|
if (!session?.user && homeVariant !== "lovart") {
|
|
redirect("/login");
|
|
}
|
|
|
|
if (homeVariant === "lovart") {
|
|
return (
|
|
<LovartHome
|
|
user={
|
|
session?.user
|
|
? {
|
|
id: session.user.id,
|
|
email: session.user.email,
|
|
name: session.user.name,
|
|
type: session.user.type,
|
|
}
|
|
: null
|
|
}
|
|
isAuthenticated={Boolean(session?.user)}
|
|
siteName={siteSettings.siteName || "AI Chatbot"}
|
|
siteLogo={siteSettings.siteLogo || siteSettings.siteLogoDark || ""}
|
|
surpriseCategories={surpriseCategories}
|
|
heroPromoText={siteSettings.lovartPromoText}
|
|
heroPromoActionText={siteSettings.lovartPromoActionText}
|
|
heroTitleText={siteSettings.lovartHeroTitle}
|
|
heroSubtitleText={siteSettings.lovartHeroSubtitle}
|
|
/>
|
|
);
|
|
}
|
|
|
|
const modelIdFromCookie = cookieStore.get("chat-model");
|
|
|
|
let initialModelId = modelIdFromCookie?.value;
|
|
const currentUser = session?.user?.id
|
|
? await getUserById({ id: session.user.id }).catch(() => undefined)
|
|
: undefined;
|
|
const allowHiddenModels =
|
|
session?.user?.type === "admin" || Boolean(currentUser?.isHighVip);
|
|
const defaultModel = await getDefaultAiModel();
|
|
const enabledModels = await getEnabledAiModelsWithProvider(false, true);
|
|
const visibleModels = enabledModels.filter(
|
|
({ model }) =>
|
|
!isAiModelAgentAuto(model) &&
|
|
(allowHiddenModels || !model.isHidden)
|
|
);
|
|
const preferredImageModels = visibleModels.filter(
|
|
({ model, provider }) =>
|
|
model.supportsImageGen &&
|
|
!isVideoModelDescriptor({
|
|
providerType: provider.type,
|
|
modelId: model.modelId,
|
|
capabilities: model.capabilities,
|
|
supportsImageGen: model.supportsImageGen,
|
|
})
|
|
);
|
|
const nanoBananaModel = preferredImageModels.find(({ model }) =>
|
|
isNanoBananaProModel(model)
|
|
);
|
|
const cookieModel = initialModelId
|
|
? visibleModels.find(({ model }) => model.id === initialModelId)
|
|
: undefined;
|
|
|
|
if (
|
|
!initialModelId ||
|
|
!cookieModel
|
|
) {
|
|
if (nanoBananaModel) {
|
|
initialModelId = nanoBananaModel.model.id;
|
|
} else if (
|
|
defaultModel &&
|
|
!isAiModelAgentAuto(defaultModel) &&
|
|
(allowHiddenModels || !defaultModel.isHidden) &&
|
|
preferredImageModels.some(({ model }) => model.id === defaultModel.id)
|
|
) {
|
|
initialModelId = defaultModel.id;
|
|
} else if (preferredImageModels.length > 0) {
|
|
const preferredDefaultImageModel = preferredImageModels.find(
|
|
({ model }) => model.isDefault
|
|
);
|
|
initialModelId = (preferredDefaultImageModel || preferredImageModels[0]).model.id;
|
|
} else if (
|
|
defaultModel &&
|
|
!isAiModelAgentAuto(defaultModel) &&
|
|
(allowHiddenModels || !defaultModel.isHidden)
|
|
) {
|
|
initialModelId = defaultModel.id;
|
|
} else if (visibleModels.length > 0) {
|
|
initialModelId = visibleModels[0].model.id;
|
|
}
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Chat
|
|
autoResume={false}
|
|
id={id}
|
|
initialChatModel={initialModelId || ""}
|
|
initialMessages={[]}
|
|
initialVisibilityType="private"
|
|
isReadonly={false}
|
|
key={id}
|
|
userType={session?.user?.type}
|
|
/>
|
|
<DataStreamHandler />
|
|
</>
|
|
);
|
|
}
|