Merge 4c6e056261
into 7ec201d011
This commit is contained in:
commit
7681935395
5 changed files with 99 additions and 20 deletions
|
@ -1,17 +1,18 @@
|
|||
'use client';
|
||||
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { Document } from '@langchain/core/documents';
|
||||
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 {toast} from 'sonner';
|
||||
import {useSearchParams} from 'next/navigation';
|
||||
import {getSuggestions} from '@/lib/actions';
|
||||
import {Settings} from 'lucide-react';
|
||||
import SettingsDialog from './SettingsDialog';
|
||||
import NextError from 'next/error';
|
||||
import {Mcid} from "@/lib/mcid";
|
||||
|
||||
export type Message = {
|
||||
messageId: string;
|
||||
|
@ -140,7 +141,7 @@ const useSocket = (
|
|||
if (
|
||||
Object.keys(chatModelProviders).length > 0 &&
|
||||
(((!openAIBaseURL || !openAIPIKey) &&
|
||||
chatModelProvider === 'custom_openai') ||
|
||||
chatModelProvider === 'custom_openai') ||
|
||||
!chatModelProviders[chatModelProvider])
|
||||
) {
|
||||
const chatModelProvidersKeys = Object.keys(chatModelProviders);
|
||||
|
@ -173,7 +174,7 @@ const useSocket = (
|
|||
Object.keys(chatModelProviders[chatModelProvider]).length > 0
|
||||
? chatModelProvider
|
||||
: Object.keys(chatModelProviders)[0]
|
||||
],
|
||||
],
|
||||
)[0];
|
||||
localStorage.setItem('chatModel', chatModel);
|
||||
}
|
||||
|
@ -382,10 +383,10 @@ const loadMessages = async (
|
|||
setIsMessagesLoaded(true);
|
||||
};
|
||||
|
||||
const ChatWindow = ({ id }: { id?: string }) => {
|
||||
const ChatWindow = ({id}: { id?: string }) => {
|
||||
const searchParams = useSearchParams();
|
||||
const initialMessage = searchParams.get('q');
|
||||
|
||||
const [userId, setUserId] = useState<string | undefined>();
|
||||
const [chatId, setChatId] = useState<string | undefined>(id);
|
||||
const [newChatCreated, setNewChatCreated] = useState(false);
|
||||
|
||||
|
@ -410,6 +411,7 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
|||
|
||||
const [focusMode, setFocusMode] = useState('webSearch');
|
||||
const [optimizationMode, setOptimizationMode] = useState('speed');
|
||||
const [copilotEnabled, setCopilotEnabled] = useState(true);
|
||||
|
||||
const [isMessagesLoaded, setIsMessagesLoaded] = useState(false);
|
||||
|
||||
|
@ -417,6 +419,33 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
|||
|
||||
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const initializeUserId = () => {
|
||||
try {
|
||||
// 从 localStorage 读取现有用户 ID
|
||||
const storedUserId = localStorage.getItem('userId');
|
||||
|
||||
if (storedUserId) {
|
||||
setUserId(storedUserId);
|
||||
console.debug('Using existing user ID:', storedUserId);
|
||||
} else {
|
||||
const newUserId = new Mcid().generate().toString();
|
||||
|
||||
localStorage.setItem('userId', newUserId);
|
||||
setUserId(newUserId);
|
||||
console.debug('Generated new user ID:', newUserId);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error initializing user ID:', error);
|
||||
const fallbackId = "1234567890";
|
||||
localStorage.setItem('userId', fallbackId);
|
||||
setUserId(fallbackId);
|
||||
}
|
||||
};
|
||||
|
||||
initializeUserId();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
chatId &&
|
||||
|
@ -437,7 +466,7 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
|||
} else if (!chatId) {
|
||||
setNewChatCreated(true);
|
||||
setIsMessagesLoaded(true);
|
||||
setChatId(crypto.randomBytes(20).toString('hex'));
|
||||
setChatId(new Mcid().generate().toString());
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
@ -465,7 +494,7 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
|||
} else {
|
||||
setIsReady(false);
|
||||
}
|
||||
}, [isMessagesLoaded, isWSReady]);
|
||||
}, [isMessagesLoaded, isWSReady, userId]);
|
||||
|
||||
const sendMessage = async (message: string, messageId?: string) => {
|
||||
if (loading) return;
|
||||
|
@ -481,11 +510,12 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
|||
let recievedMessage = '';
|
||||
let added = false;
|
||||
|
||||
messageId = messageId ?? crypto.randomBytes(7).toString('hex');
|
||||
messageId = messageId ?? new Mcid().generate().toString();
|
||||
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: 'message',
|
||||
userId:userId,
|
||||
message: {
|
||||
messageId: messageId,
|
||||
chatId: chatId!,
|
||||
|
@ -493,6 +523,7 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
|||
},
|
||||
files: fileIds,
|
||||
focusMode: focusMode,
|
||||
copilotEnabled: copilotEnabled,
|
||||
optimizationMode: optimizationMode,
|
||||
history: [...chatHistory, ['human', message]],
|
||||
}),
|
||||
|
@ -556,7 +587,7 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
|||
setMessages((prev) =>
|
||||
prev.map((message) => {
|
||||
if (message.messageId === data.messageId) {
|
||||
return { ...message, content: message.content + data.data };
|
||||
return {...message, content: message.content + data.data};
|
||||
}
|
||||
|
||||
return message;
|
||||
|
@ -589,7 +620,7 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
|||
setMessages((prev) =>
|
||||
prev.map((msg) => {
|
||||
if (msg.messageId === lastMsg.messageId) {
|
||||
return { ...msg, suggestions: suggestions };
|
||||
return {...msg, suggestions: suggestions};
|
||||
}
|
||||
return msg;
|
||||
}),
|
||||
|
@ -639,19 +670,19 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
|||
Failed to connect to the server. Please try again later.
|
||||
</p>
|
||||
</div>
|
||||
<SettingsDialog isOpen={isSettingsOpen} setIsOpen={setIsSettingsOpen} />
|
||||
<SettingsDialog isOpen={isSettingsOpen} setIsOpen={setIsSettingsOpen}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return isReady ? (
|
||||
notFound ? (
|
||||
<NextError statusCode={404} />
|
||||
<NextError statusCode={404}/>
|
||||
) : (
|
||||
<div>
|
||||
{messages.length > 0 ? (
|
||||
<>
|
||||
<Navbar chatId={chatId!} messages={messages} />
|
||||
<Navbar chatId={chatId!} messages={messages}/>
|
||||
<Chat
|
||||
loading={loading}
|
||||
messages={messages}
|
||||
|
@ -668,6 +699,8 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
|||
<EmptyChat
|
||||
sendMessage={sendMessage}
|
||||
focusMode={focusMode}
|
||||
copilotEnabled={copilotEnabled}
|
||||
setCopilotEnabled={setCopilotEnabled}
|
||||
setFocusMode={setFocusMode}
|
||||
optimizationMode={optimizationMode}
|
||||
setOptimizationMode={setOptimizationMode}
|
||||
|
|
|
@ -8,6 +8,8 @@ const EmptyChat = ({
|
|||
sendMessage,
|
||||
focusMode,
|
||||
setFocusMode,
|
||||
copilotEnabled,
|
||||
setCopilotEnabled,
|
||||
optimizationMode,
|
||||
setOptimizationMode,
|
||||
fileIds,
|
||||
|
@ -18,6 +20,8 @@ const EmptyChat = ({
|
|||
sendMessage: (message: string) => void;
|
||||
focusMode: string;
|
||||
setFocusMode: (mode: string) => void;
|
||||
copilotEnabled: boolean;
|
||||
setCopilotEnabled: (enabled: boolean) => void;
|
||||
optimizationMode: string;
|
||||
setOptimizationMode: (mode: string) => void;
|
||||
fileIds: string[];
|
||||
|
@ -44,6 +48,8 @@ const EmptyChat = ({
|
|||
sendMessage={sendMessage}
|
||||
focusMode={focusMode}
|
||||
setFocusMode={setFocusMode}
|
||||
copilotEnabled={copilotEnabled}
|
||||
setCopilotEnabled={setCopilotEnabled}
|
||||
optimizationMode={optimizationMode}
|
||||
setOptimizationMode={setOptimizationMode}
|
||||
fileIds={fileIds}
|
||||
|
|
|
@ -11,6 +11,8 @@ const EmptyChatMessageInput = ({
|
|||
sendMessage,
|
||||
focusMode,
|
||||
setFocusMode,
|
||||
copilotEnabled,
|
||||
setCopilotEnabled,
|
||||
optimizationMode,
|
||||
setOptimizationMode,
|
||||
fileIds,
|
||||
|
@ -23,12 +25,13 @@ const EmptyChatMessageInput = ({
|
|||
setFocusMode: (mode: string) => void;
|
||||
optimizationMode: string;
|
||||
setOptimizationMode: (mode: string) => void;
|
||||
copilotEnabled:boolean
|
||||
setCopilotEnabled:(mode: boolean) => void;
|
||||
fileIds: string[];
|
||||
setFileIds: (fileIds: string[]) => void;
|
||||
files: File[];
|
||||
setFiles: (files: File[]) => void;
|
||||
}) => {
|
||||
const [copilotEnabled, setCopilotEnabled] = useState(false);
|
||||
const [message, setMessage] = useState('');
|
||||
|
||||
const inputRef = useRef<HTMLTextAreaElement | null>(null);
|
||||
|
@ -94,6 +97,7 @@ const EmptyChatMessageInput = ({
|
|||
/>
|
||||
</div>
|
||||
<div className="flex flex-row items-center space-x-1 sm:space-x-4">
|
||||
<CopilotToggle setCopilotEnabled={setCopilotEnabled} copilotEnabled={copilotEnabled}/>
|
||||
<Optimization
|
||||
optimizationMode={optimizationMode}
|
||||
setOptimizationMode={setOptimizationMode}
|
||||
|
|
|
@ -7,7 +7,7 @@ const ThemeProviderComponent = ({
|
|||
children: React.ReactNode;
|
||||
}) => {
|
||||
return (
|
||||
<ThemeProvider attribute="class" enableSystem={false} defaultTheme="dark">
|
||||
<ThemeProvider attribute="class" enableSystem={false} defaultTheme="light">
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
|
36
ui/lib/mcid.ts
Normal file
36
ui/lib/mcid.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
// utils/mcid.ts
|
||||
export class Mcid {
|
||||
private lastTimestamp = -1;
|
||||
private sequence = 0;
|
||||
|
||||
constructor(private readonly machineId: number = 0) {
|
||||
if (machineId < 0 || machineId > 255) {
|
||||
throw new Error('Machine ID must be between 0 and 255');
|
||||
}
|
||||
}
|
||||
|
||||
generate(): number {
|
||||
let now = Date.now();
|
||||
|
||||
if (now < this.lastTimestamp) {
|
||||
throw new Error('Clock moved backwards');
|
||||
}
|
||||
|
||||
if (now === this.lastTimestamp) {
|
||||
this.sequence = (this.sequence + 1) & 0xf;
|
||||
if (this.sequence === 0) {
|
||||
while (now <= this.lastTimestamp) {
|
||||
now = Date.now();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.sequence = 0;
|
||||
}
|
||||
|
||||
this.lastTimestamp = now;
|
||||
|
||||
return (
|
||||
(now * 0x1000) + (this.machineId * 16) + this.sequence
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue