2025-07-26 23:16:07 +00:00
|
|
|
import { getRepos, getSearchContexts } from '@/actions';
|
2025-07-23 18:25:15 +00:00
|
|
|
import { getUserChatHistory, getConfiguredLanguageModelsInfo, getChatInfo } from '@/features/chat/actions';
|
|
|
|
|
import { ServiceErrorException } from '@/lib/serviceError';
|
|
|
|
|
import { isServiceError } from '@/lib/utils';
|
|
|
|
|
import { ChatThreadPanel } from './components/chatThreadPanel';
|
|
|
|
|
import { notFound } from 'next/navigation';
|
|
|
|
|
import { StatusCodes } from 'http-status-codes';
|
|
|
|
|
import { TopBar } from '../../components/topBar';
|
|
|
|
|
import { ChatName } from '../components/chatName';
|
|
|
|
|
import { auth } from '@/auth';
|
|
|
|
|
import { AnimatedResizableHandle } from '@/components/ui/animatedResizableHandle';
|
|
|
|
|
import { ChatSidePanel } from '../components/chatSidePanel';
|
|
|
|
|
import { ResizablePanelGroup } from '@/components/ui/resizable';
|
|
|
|
|
|
|
|
|
|
interface PageProps {
|
2025-08-22 18:48:29 +00:00
|
|
|
params: Promise<{
|
2025-07-23 18:25:15 +00:00
|
|
|
domain: string;
|
|
|
|
|
id: string;
|
2025-08-22 18:48:29 +00:00
|
|
|
}>;
|
2025-07-23 18:25:15 +00:00
|
|
|
}
|
|
|
|
|
|
2025-08-22 18:48:29 +00:00
|
|
|
export default async function Page(props: PageProps) {
|
|
|
|
|
const params = await props.params;
|
2025-07-23 18:25:15 +00:00
|
|
|
const languageModels = await getConfiguredLanguageModelsInfo();
|
2025-09-16 06:13:29 +00:00
|
|
|
const repos = await getRepos();
|
2025-07-26 23:16:07 +00:00
|
|
|
const searchContexts = await getSearchContexts(params.domain);
|
2025-11-28 00:56:11 +00:00
|
|
|
const chatInfo = await getChatInfo({ chatId: params.id });
|
2025-07-23 18:25:15 +00:00
|
|
|
const session = await auth();
|
2025-11-28 00:56:11 +00:00
|
|
|
const chatHistory = session ? await getUserChatHistory() : [];
|
2025-07-23 18:25:15 +00:00
|
|
|
|
|
|
|
|
if (isServiceError(chatHistory)) {
|
|
|
|
|
throw new ServiceErrorException(chatHistory);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isServiceError(repos)) {
|
|
|
|
|
throw new ServiceErrorException(repos);
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-26 23:16:07 +00:00
|
|
|
if (isServiceError(searchContexts)) {
|
|
|
|
|
throw new ServiceErrorException(searchContexts);
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-23 18:25:15 +00:00
|
|
|
if (isServiceError(chatInfo)) {
|
|
|
|
|
if (chatInfo.statusCode === StatusCodes.NOT_FOUND) {
|
|
|
|
|
return notFound();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw new ServiceErrorException(chatInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { messages, name, visibility, isReadonly } = chatInfo;
|
|
|
|
|
|
|
|
|
|
const indexedRepos = repos.filter((repo) => repo.indexedAt !== undefined);
|
|
|
|
|
|
|
|
|
|
return (
|
2025-10-29 21:05:48 +00:00
|
|
|
<div className="flex flex-col h-screen w-screen">
|
2025-07-23 18:25:15 +00:00
|
|
|
<TopBar
|
|
|
|
|
domain={params.domain}
|
2025-10-18 23:31:22 +00:00
|
|
|
homePath={`/${params.domain}/chat`}
|
2025-07-23 18:25:15 +00:00
|
|
|
>
|
|
|
|
|
<div className="flex flex-row gap-2 items-center">
|
|
|
|
|
<span className="text-muted mx-2 select-none">/</span>
|
|
|
|
|
<ChatName
|
|
|
|
|
name={name}
|
|
|
|
|
visibility={visibility}
|
|
|
|
|
id={params.id}
|
|
|
|
|
isReadonly={isReadonly}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</TopBar>
|
|
|
|
|
<ResizablePanelGroup
|
|
|
|
|
direction="horizontal"
|
|
|
|
|
>
|
|
|
|
|
<ChatSidePanel
|
|
|
|
|
order={1}
|
|
|
|
|
chatHistory={chatHistory}
|
|
|
|
|
isAuthenticated={!!session}
|
|
|
|
|
isCollapsedInitially={true}
|
|
|
|
|
/>
|
|
|
|
|
<AnimatedResizableHandle />
|
|
|
|
|
<ChatThreadPanel
|
|
|
|
|
languageModels={languageModels}
|
|
|
|
|
repos={indexedRepos}
|
2025-07-26 23:16:07 +00:00
|
|
|
searchContexts={searchContexts}
|
2025-07-23 18:25:15 +00:00
|
|
|
messages={messages}
|
|
|
|
|
order={2}
|
|
|
|
|
isChatReadonly={isReadonly}
|
|
|
|
|
/>
|
|
|
|
|
</ResizablePanelGroup>
|
2025-10-29 21:05:48 +00:00
|
|
|
</div>
|
2025-07-23 18:25:15 +00:00
|
|
|
)
|
|
|
|
|
}
|