@@ -76,35 +83,73 @@ const Page = () => {
-
- {discover &&
- discover?.map((item, i) => (
-
-

-
-
- {item.title.slice(0, 100)}...
-
-
- {item.content.slice(0, 100)}...
-
-
-
- ))}
+
+ {topics.map((t, i) => (
+
setActiveTopic(t.key)}
+ >
+ {t.display}
+
+ ))}
+
+ {loading ? (
+
+ ) : (
+
+ {discover &&
+ discover?.map((item, i) => (
+
+

+
+
+ {item.title.slice(0, 100)}...
+
+
+ {item.content.slice(0, 100)}...
+
+
+
+ ))}
+
+ )}
>
);
diff --git a/src/app/globals.css b/src/app/globals.css
index f75daca..6bdc1a8 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -11,3 +11,11 @@
display: none;
}
}
+
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+ select,
+ textarea,
+ input {
+ font-size: 16px !important;
+ }
+}
diff --git a/src/app/manifest.ts b/src/app/manifest.ts
new file mode 100644
index 0000000..792e752
--- /dev/null
+++ b/src/app/manifest.ts
@@ -0,0 +1,54 @@
+import type { MetadataRoute } from 'next';
+
+export default function manifest(): MetadataRoute.Manifest {
+ return {
+ name: 'Perplexica - Chat with the internet',
+ short_name: 'Perplexica',
+ description:
+ 'Perplexica is an AI powered chatbot that is connected to the internet.',
+ start_url: '/',
+ display: 'standalone',
+ background_color: '#0a0a0a',
+ theme_color: '#0a0a0a',
+ screenshots: [
+ {
+ src: '/screenshots/p1.png',
+ form_factor: 'wide',
+ sizes: '2560x1600',
+ },
+ {
+ src: '/screenshots/p2.png',
+ form_factor: 'wide',
+ sizes: '2560x1600',
+ },
+ {
+ src: '/screenshots/p1_small.png',
+ form_factor: 'narrow',
+ sizes: '828x1792',
+ },
+ {
+ src: '/screenshots/p2_small.png',
+ form_factor: 'narrow',
+ sizes: '828x1792',
+ },
+ ],
+ icons: [
+ {
+ src: '/icon-50.png',
+ sizes: '50x50',
+ type: 'image/png' as const,
+ },
+ {
+ src: '/icon-100.png',
+ sizes: '100x100',
+ type: 'image/png',
+ },
+ {
+ src: '/icon.png',
+ sizes: '440x440',
+ type: 'image/png',
+ purpose: 'any',
+ },
+ ],
+ };
+}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index e18aca9..25981b5 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,4 +1,5 @@
import ChatWindow from '@/components/ChatWindow';
+import { ChatProvider } from '@/lib/hooks/useChat';
import { Metadata } from 'next';
import { Suspense } from 'react';
@@ -11,7 +12,9 @@ const Home = () => {
return (
-
+
+
+
);
diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx
index 05338c3..6fb8255 100644
--- a/src/app/settings/page.tsx
+++ b/src/app/settings/page.tsx
@@ -21,8 +21,10 @@ interface SettingsType {
anthropicApiKey: string;
geminiApiKey: string;
ollamaApiUrl: string;
+ ollamaApiKey: string;
lmStudioApiUrl: string;
deepseekApiKey: string;
+ aimlApiKey: string;
customOpenaiApiKey: string;
customOpenaiApiUrl: string;
customOpenaiModelName: string;
@@ -143,15 +145,17 @@ const Page = () => {
const [selectedEmbeddingModel, setSelectedEmbeddingModel] = useState<
string | null
>(null);
- const [isLoading, setIsLoading] = useState(false);
+ const [isLoading, setIsLoading] = useState(true);
const [automaticImageSearch, setAutomaticImageSearch] = useState(false);
const [automaticVideoSearch, setAutomaticVideoSearch] = useState(false);
const [systemInstructions, setSystemInstructions] = useState
('');
+ const [measureUnit, setMeasureUnit] = useState<'Imperial' | 'Metric'>(
+ 'Metric',
+ );
const [savingStates, setSavingStates] = useState>({});
useEffect(() => {
const fetchConfig = async () => {
- setIsLoading(true);
const res = await fetch(`/api/config`, {
headers: {
'Content-Type': 'application/json',
@@ -210,6 +214,10 @@ const Page = () => {
setSystemInstructions(localStorage.getItem('systemInstructions')!);
+ setMeasureUnit(
+ localStorage.getItem('measureUnit')! as 'Imperial' | 'Metric',
+ );
+
setIsLoading(false);
};
@@ -368,6 +376,8 @@ const Page = () => {
localStorage.setItem('embeddingModel', value);
} else if (key === 'systemInstructions') {
localStorage.setItem('systemInstructions', value);
+ } else if (key === 'measureUnit') {
+ localStorage.setItem('measureUnit', value.toString());
}
} catch (err) {
console.error('Failed to save:', err);
@@ -416,13 +426,35 @@ const Page = () => {
) : (
config && (
-
+
+
+
+ Measurement Units
+
+
@@ -516,7 +548,7 @@ const Page = () => {
+
+
+ Ollama API Key (Can be left blank)
+
+
{
+ setConfig((prev) => ({
+ ...prev!,
+ ollamaApiKey: e.target.value,
+ }));
+ }}
+ onSave={(value) => saveConfig('ollamaApiKey', value)}
+ />
+
+
GROQ API Key
@@ -863,6 +914,25 @@ const Page = () => {
/>
+
+
+ AI/ML API Key
+
+
{
+ setConfig((prev) => ({
+ ...prev!,
+ aimlApiKey: e.target.value,
+ }));
+ }}
+ onSave={(value) => saveConfig('aimlApiKey', value)}
+ />
+
+
LM Studio API URL
diff --git a/src/components/Chat.tsx b/src/components/Chat.tsx
index 0cf125b..a5d8cf9 100644
--- a/src/components/Chat.tsx
+++ b/src/components/Chat.tsx
@@ -5,28 +5,11 @@ import MessageInput from './MessageInput';
import { File, Message } from './ChatWindow';
import MessageBox from './MessageBox';
import MessageBoxLoading from './MessageBoxLoading';
+import { useChat } from '@/lib/hooks/useChat';
+
+const Chat = () => {
+ const { messages, loading, messageAppeared } = useChat();
-const Chat = ({
- loading,
- messages,
- sendMessage,
- messageAppeared,
- rewrite,
- fileIds,
- setFileIds,
- files,
- setFiles,
-}: {
- messages: Message[];
- sendMessage: (message: string) => void;
- loading: boolean;
- messageAppeared: boolean;
- rewrite: (messageId: string) => void;
- fileIds: string[];
- setFileIds: (fileIds: string[]) => void;
- files: File[];
- setFiles: (files: File[]) => void;
-}) => {
const [dividerWidth, setDividerWidth] = useState(0);
const dividerRef = useRef(null);
const messageEnd = useRef(null);
@@ -72,12 +55,8 @@ const Chat = ({
key={i}
message={msg}
messageIndex={i}
- history={messages}
- loading={loading}
dividerRef={isLast ? dividerRef : undefined}
isLast={isLast}
- rewrite={rewrite}
- sendMessage={sendMessage}
/>
{!isLast && msg.role === 'assistant' && (
@@ -92,14 +71,7 @@ const Chat = ({
className="bottom-24 lg:bottom-10 fixed z-40"
style={{ width: dividerWidth }}
>
-
+
)}
diff --git a/src/components/ChatWindow.tsx b/src/components/ChatWindow.tsx
index 93c8a0c..0d40c83 100644
--- a/src/components/ChatWindow.tsx
+++ b/src/components/ChatWindow.tsx
@@ -1,17 +1,13 @@
'use client';
-import { useEffect, useRef, useState } from 'react';
import { Document } from '@langchain/core/documents';
import Navbar from './Navbar';
import Chat from './Chat';
import EmptyChat from './EmptyChat';
-import crypto from 'crypto';
-import { toast } from 'sonner';
-import { useSearchParams } from 'next/navigation';
-import { getSuggestions } from '@/lib/actions';
import { Settings } from 'lucide-react';
import Link from 'next/link';
import NextError from 'next/error';
+import { useChat } from '@/lib/hooks/useChat';
export type Message = {
messageId: string;
@@ -29,512 +25,8 @@ export interface File {
fileId: string;
}
-interface ChatModelProvider {
- name: string;
- provider: string;
-}
-
-interface EmbeddingModelProvider {
- name: string;
- provider: string;
-}
-
-const checkConfig = async (
- setChatModelProvider: (provider: ChatModelProvider) => void,
- setEmbeddingModelProvider: (provider: EmbeddingModelProvider) => void,
- setIsConfigReady: (ready: boolean) => void,
- setHasError: (hasError: boolean) => void,
-) => {
- try {
- let chatModel = localStorage.getItem('chatModel');
- let chatModelProvider = localStorage.getItem('chatModelProvider');
- let embeddingModel = localStorage.getItem('embeddingModel');
- let embeddingModelProvider = localStorage.getItem('embeddingModelProvider');
-
- const autoImageSearch = localStorage.getItem('autoImageSearch');
- const autoVideoSearch = localStorage.getItem('autoVideoSearch');
-
- if (!autoImageSearch) {
- localStorage.setItem('autoImageSearch', 'true');
- }
-
- if (!autoVideoSearch) {
- localStorage.setItem('autoVideoSearch', 'false');
- }
-
- const providers = await fetch(`/api/models`, {
- headers: {
- 'Content-Type': 'application/json',
- },
- }).then(async (res) => {
- if (!res.ok)
- throw new Error(
- `Failed to fetch models: ${res.status} ${res.statusText}`,
- );
- return res.json();
- });
-
- if (
- !chatModel ||
- !chatModelProvider ||
- !embeddingModel ||
- !embeddingModelProvider
- ) {
- if (!chatModel || !chatModelProvider) {
- const chatModelProviders = providers.chatModelProviders;
-
- chatModelProvider =
- chatModelProvider || Object.keys(chatModelProviders)[0];
-
- chatModel = Object.keys(chatModelProviders[chatModelProvider])[0];
-
- if (!chatModelProviders || Object.keys(chatModelProviders).length === 0)
- return toast.error('No chat models available');
- }
-
- if (!embeddingModel || !embeddingModelProvider) {
- const embeddingModelProviders = providers.embeddingModelProviders;
-
- if (
- !embeddingModelProviders ||
- Object.keys(embeddingModelProviders).length === 0
- )
- return toast.error('No embedding models available');
-
- embeddingModelProvider = Object.keys(embeddingModelProviders)[0];
- embeddingModel = Object.keys(
- embeddingModelProviders[embeddingModelProvider],
- )[0];
- }
-
- localStorage.setItem('chatModel', chatModel!);
- localStorage.setItem('chatModelProvider', chatModelProvider);
- localStorage.setItem('embeddingModel', embeddingModel!);
- localStorage.setItem('embeddingModelProvider', embeddingModelProvider);
- } else {
- const chatModelProviders = providers.chatModelProviders;
- const embeddingModelProviders = providers.embeddingModelProviders;
-
- if (
- Object.keys(chatModelProviders).length > 0 &&
- !chatModelProviders[chatModelProvider]
- ) {
- const chatModelProvidersKeys = Object.keys(chatModelProviders);
- chatModelProvider =
- chatModelProvidersKeys.find(
- (key) => Object.keys(chatModelProviders[key]).length > 0,
- ) || chatModelProvidersKeys[0];
-
- localStorage.setItem('chatModelProvider', chatModelProvider);
- }
-
- if (
- chatModelProvider &&
- !chatModelProviders[chatModelProvider][chatModel]
- ) {
- chatModel = Object.keys(
- chatModelProviders[
- Object.keys(chatModelProviders[chatModelProvider]).length > 0
- ? chatModelProvider
- : Object.keys(chatModelProviders)[0]
- ],
- )[0];
- localStorage.setItem('chatModel', chatModel);
- }
-
- if (
- Object.keys(embeddingModelProviders).length > 0 &&
- !embeddingModelProviders[embeddingModelProvider]
- ) {
- embeddingModelProvider = Object.keys(embeddingModelProviders)[0];
- localStorage.setItem('embeddingModelProvider', embeddingModelProvider);
- }
-
- if (
- embeddingModelProvider &&
- !embeddingModelProviders[embeddingModelProvider][embeddingModel]
- ) {
- embeddingModel = Object.keys(
- embeddingModelProviders[embeddingModelProvider],
- )[0];
- localStorage.setItem('embeddingModel', embeddingModel);
- }
- }
-
- setChatModelProvider({
- name: chatModel!,
- provider: chatModelProvider,
- });
-
- setEmbeddingModelProvider({
- name: embeddingModel!,
- provider: embeddingModelProvider,
- });
-
- setIsConfigReady(true);
- } catch (err) {
- console.error('An error occurred while checking the configuration:', err);
- setIsConfigReady(false);
- setHasError(true);
- }
-};
-
-const loadMessages = async (
- chatId: string,
- setMessages: (messages: Message[]) => void,
- setIsMessagesLoaded: (loaded: boolean) => void,
- setChatHistory: (history: [string, string][]) => void,
- setFocusMode: (mode: string) => void,
- setNotFound: (notFound: boolean) => void,
- setFiles: (files: File[]) => void,
- setFileIds: (fileIds: string[]) => void,
-) => {
- const res = await fetch(`/api/chats/${chatId}`, {
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json',
- },
- });
-
- if (res.status === 404) {
- setNotFound(true);
- setIsMessagesLoaded(true);
- return;
- }
-
- const data = await res.json();
-
- const messages = data.messages.map((msg: any) => {
- return {
- ...msg,
- ...JSON.parse(msg.metadata),
- };
- }) as Message[];
-
- setMessages(messages);
-
- const history = messages.map((msg) => {
- return [msg.role, msg.content];
- }) as [string, string][];
-
- console.debug(new Date(), 'app:messages_loaded');
-
- document.title = messages[0].content;
-
- const files = data.chat.files.map((file: any) => {
- return {
- fileName: file.name,
- fileExtension: file.name.split('.').pop(),
- fileId: file.fileId,
- };
- });
-
- setFiles(files);
- setFileIds(files.map((file: File) => file.fileId));
-
- setChatHistory(history);
- setFocusMode(data.chat.focusMode);
- setIsMessagesLoaded(true);
-};
-
-const ChatWindow = ({ id }: { id?: string }) => {
- const searchParams = useSearchParams();
- const initialMessage = searchParams.get('q');
-
- const [chatId, setChatId] = useState(id);
- const [newChatCreated, setNewChatCreated] = useState(false);
-
- const [chatModelProvider, setChatModelProvider] = useState(
- {
- name: '',
- provider: '',
- },
- );
-
- const [embeddingModelProvider, setEmbeddingModelProvider] =
- useState({
- name: '',
- provider: '',
- });
-
- const [isConfigReady, setIsConfigReady] = useState(false);
- const [hasError, setHasError] = useState(false);
- const [isReady, setIsReady] = useState(false);
-
- useEffect(() => {
- checkConfig(
- setChatModelProvider,
- setEmbeddingModelProvider,
- setIsConfigReady,
- setHasError,
- );
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
-
- const [loading, setLoading] = useState(false);
- const [messageAppeared, setMessageAppeared] = useState(false);
-
- const [chatHistory, setChatHistory] = useState<[string, string][]>([]);
- const [messages, setMessages] = useState([]);
-
- const [files, setFiles] = useState([]);
- const [fileIds, setFileIds] = useState([]);
-
- const [focusMode, setFocusMode] = useState('webSearch');
- const [optimizationMode, setOptimizationMode] = useState('speed');
-
- const [isMessagesLoaded, setIsMessagesLoaded] = useState(false);
-
- const [notFound, setNotFound] = useState(false);
-
- useEffect(() => {
- if (
- chatId &&
- !newChatCreated &&
- !isMessagesLoaded &&
- messages.length === 0
- ) {
- loadMessages(
- chatId,
- setMessages,
- setIsMessagesLoaded,
- setChatHistory,
- setFocusMode,
- setNotFound,
- setFiles,
- setFileIds,
- );
- } else if (!chatId) {
- setNewChatCreated(true);
- setIsMessagesLoaded(true);
- setChatId(crypto.randomBytes(20).toString('hex'));
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
-
- const messagesRef = useRef([]);
-
- useEffect(() => {
- messagesRef.current = messages;
- }, [messages]);
-
- useEffect(() => {
- if (isMessagesLoaded && isConfigReady) {
- setIsReady(true);
- console.debug(new Date(), 'app:ready');
- } else {
- setIsReady(false);
- }
- }, [isMessagesLoaded, isConfigReady]);
-
- const sendMessage = async (message: string, messageId?: string) => {
- if (loading) return;
- if (!isConfigReady) {
- toast.error('Cannot send message before the configuration is ready');
- return;
- }
-
- setLoading(true);
- setMessageAppeared(false);
-
- let sources: Document[] | undefined = undefined;
- let recievedMessage = '';
- let added = false;
-
- messageId = messageId ?? crypto.randomBytes(7).toString('hex');
-
- setMessages((prevMessages) => [
- ...prevMessages,
- {
- content: message,
- messageId: messageId,
- chatId: chatId!,
- role: 'user',
- createdAt: new Date(),
- },
- ]);
-
- const messageHandler = async (data: any) => {
- if (data.type === 'error') {
- toast.error(data.data);
- setLoading(false);
- return;
- }
-
- if (data.type === 'sources') {
- sources = data.data;
- if (!added) {
- setMessages((prevMessages) => [
- ...prevMessages,
- {
- content: '',
- messageId: data.messageId,
- chatId: chatId!,
- role: 'assistant',
- sources: sources,
- createdAt: new Date(),
- },
- ]);
- added = true;
- }
- setMessageAppeared(true);
- }
-
- if (data.type === 'message') {
- if (!added) {
- setMessages((prevMessages) => [
- ...prevMessages,
- {
- content: data.data,
- messageId: data.messageId,
- chatId: chatId!,
- role: 'assistant',
- sources: sources,
- createdAt: new Date(),
- },
- ]);
- added = true;
- }
-
- setMessages((prev) =>
- prev.map((message) => {
- if (message.messageId === data.messageId) {
- return { ...message, content: message.content + data.data };
- }
-
- return message;
- }),
- );
-
- recievedMessage += data.data;
- setMessageAppeared(true);
- }
-
- if (data.type === 'messageEnd') {
- setChatHistory((prevHistory) => [
- ...prevHistory,
- ['human', message],
- ['assistant', recievedMessage],
- ]);
-
- setLoading(false);
-
- const lastMsg = messagesRef.current[messagesRef.current.length - 1];
-
- const autoImageSearch = localStorage.getItem('autoImageSearch');
- const autoVideoSearch = localStorage.getItem('autoVideoSearch');
-
- if (autoImageSearch === 'true') {
- document
- .getElementById(`search-images-${lastMsg.messageId}`)
- ?.click();
- }
-
- if (autoVideoSearch === 'true') {
- document
- .getElementById(`search-videos-${lastMsg.messageId}`)
- ?.click();
- }
-
- if (
- lastMsg.role === 'assistant' &&
- lastMsg.sources &&
- lastMsg.sources.length > 0 &&
- !lastMsg.suggestions
- ) {
- const suggestions = await getSuggestions(messagesRef.current);
- setMessages((prev) =>
- prev.map((msg) => {
- if (msg.messageId === lastMsg.messageId) {
- return { ...msg, suggestions: suggestions };
- }
- return msg;
- }),
- );
- }
- }
- };
-
- const res = await fetch('/api/chat', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- content: message,
- message: {
- messageId: messageId,
- chatId: chatId!,
- content: message,
- },
- chatId: chatId!,
- files: fileIds,
- focusMode: focusMode,
- optimizationMode: optimizationMode,
- history: chatHistory,
- chatModel: {
- name: chatModelProvider.name,
- provider: chatModelProvider.provider,
- },
- embeddingModel: {
- name: embeddingModelProvider.name,
- provider: embeddingModelProvider.provider,
- },
- systemInstructions: localStorage.getItem('systemInstructions'),
- }),
- });
-
- if (!res.body) throw new Error('No response body');
-
- const reader = res.body?.getReader();
- const decoder = new TextDecoder('utf-8');
-
- let partialChunk = '';
-
- while (true) {
- const { value, done } = await reader.read();
- if (done) break;
-
- partialChunk += decoder.decode(value, { stream: true });
-
- try {
- const messages = partialChunk.split('\n');
- for (const msg of messages) {
- if (!msg.trim()) continue;
- const json = JSON.parse(msg);
- messageHandler(json);
- }
- partialChunk = '';
- } catch (error) {
- console.warn('Incomplete JSON, waiting for next chunk...');
- }
- }
- };
-
- const rewrite = (messageId: string) => {
- const index = messages.findIndex((msg) => msg.messageId === messageId);
-
- if (index === -1) return;
-
- const message = messages[index - 1];
-
- setMessages((prev) => {
- return [...prev.slice(0, messages.length > 2 ? index - 1 : 0)];
- });
- setChatHistory((prev) => {
- return [...prev.slice(0, messages.length > 2 ? index - 1 : 0)];
- });
-
- sendMessage(message.content, message.messageId);
- };
-
- useEffect(() => {
- if (isReady && initialMessage && isConfigReady) {
- sendMessage(initialMessage);
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [isConfigReady, isReady, initialMessage]);
-
+const ChatWindow = () => {
+ const { hasError, isReady, notFound, messages } = useChat();
if (hasError) {
return (
@@ -559,31 +51,11 @@ const ChatWindow = ({ id }: { id?: string }) => {
{messages.length > 0 ? (
<>
-
-
+
+
>
) : (
-
+
)}
)
diff --git a/src/components/EmptyChat.tsx b/src/components/EmptyChat.tsx
index 838849f..e40a338 100644
--- a/src/components/EmptyChat.tsx
+++ b/src/components/EmptyChat.tsx
@@ -1,32 +1,11 @@
import { Settings } from 'lucide-react';
import EmptyChatMessageInput from './EmptyChatMessageInput';
-import { useState } from 'react';
import { File } from './ChatWindow';
import Link from 'next/link';
+import WeatherWidget from './WeatherWidget';
+import NewsArticleWidget from './NewsArticleWidget';
-const EmptyChat = ({
- sendMessage,
- focusMode,
- setFocusMode,
- optimizationMode,
- setOptimizationMode,
- fileIds,
- setFileIds,
- files,
- setFiles,
-}: {
- sendMessage: (message: string) => void;
- focusMode: string;
- setFocusMode: (mode: string) => void;
- optimizationMode: string;
- setOptimizationMode: (mode: string) => void;
- fileIds: string[];
- setFileIds: (fileIds: string[]) => void;
- files: File[];
- setFiles: (files: File[]) => void;
-}) => {
- const [isSettingsOpen, setIsSettingsOpen] = useState(false);
-
+const EmptyChat = () => {
return (
@@ -34,21 +13,21 @@ const EmptyChat = ({
-
-
- Research begins here.
-
-
+
+
+
+ Research begins here.
+
+
+
+
);
diff --git a/src/components/EmptyChatMessageInput.tsx b/src/components/EmptyChatMessageInput.tsx
index 43d1e28..3c5ff6b 100644
--- a/src/components/EmptyChatMessageInput.tsx
+++ b/src/components/EmptyChatMessageInput.tsx
@@ -1,34 +1,15 @@
import { ArrowRight } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import TextareaAutosize from 'react-textarea-autosize';
-import CopilotToggle from './MessageInputActions/Copilot';
import Focus from './MessageInputActions/Focus';
import Optimization from './MessageInputActions/Optimization';
import Attach from './MessageInputActions/Attach';
-import { File } from './ChatWindow';
+import { useChat } from '@/lib/hooks/useChat';
-const EmptyChatMessageInput = ({
- sendMessage,
- focusMode,
- setFocusMode,
- optimizationMode,
- setOptimizationMode,
- fileIds,
- setFileIds,
- files,
- setFiles,
-}: {
- sendMessage: (message: string) => void;
- focusMode: string;
- setFocusMode: (mode: string) => void;
- optimizationMode: string;
- setOptimizationMode: (mode: string) => void;
- fileIds: string[];
- setFileIds: (fileIds: string[]) => void;
- files: File[];
- setFiles: (files: File[]) => void;
-}) => {
- const [copilotEnabled, setCopilotEnabled] = useState(false);
+const EmptyChatMessageInput = () => {
+ const { sendMessage } = useChat();
+
+ /* const [copilotEnabled, setCopilotEnabled] = useState(false); */
const [message, setMessage] = useState('');
const inputRef = useRef
(null);
@@ -84,20 +65,11 @@ const EmptyChatMessageInput = ({
/>
-
+