111 lines
3.5 KiB
TypeScript
111 lines
3.5 KiB
TypeScript
import { cookies } from "next/headers";
|
|
import { redirect } from "next/navigation";
|
|
import { Suspense } from "react";
|
|
import { ClassicChatStart } from "@/components/classic-chat-start";
|
|
import { isVideoModelDescriptor } from "@/lib/ai/model-classification";
|
|
import { isAiModelAgentAuto } from "@/lib/db/ai-model-flags";
|
|
import {
|
|
getDefaultAiModel,
|
|
getEnabledAiModelsWithProvider,
|
|
getUserById,
|
|
} from "@/lib/db/queries";
|
|
import { generateUUID } from "@/lib/utils";
|
|
import { auth } from "../../(auth)/auth";
|
|
|
|
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 ClassicPage() {
|
|
return (
|
|
<Suspense fallback={<div className="flex h-dvh" />}>
|
|
<ClassicChatPage />
|
|
</Suspense>
|
|
);
|
|
}
|
|
|
|
async function ClassicChatPage() {
|
|
const id = generateUUID();
|
|
const [session, cookieStore] = await Promise.all([auth(), cookies()]);
|
|
|
|
if (!session?.user) {
|
|
redirect("/login");
|
|
}
|
|
|
|
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 (
|
|
<ClassicChatStart
|
|
id={id}
|
|
initialModelId={initialModelId || ""}
|
|
userType={session.user.type}
|
|
/>
|
|
);
|
|
}
|