Guest User

Untitled

a guest
Feb 17th, 2025
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
TypeScript 5.57 KB | Source Code | 0 0
  1. The part of my chat-area.tsx component that handles sending messages:
  2. function handleSendMessage() {
  3.         if (!input.trim() || isLoading) return;
  4.  
  5.         setIsLoading(true);
  6.         const currentMessage = input;
  7.         setInput("");
  8.  
  9.         // Add user message immediately for better UX
  10.         setMessages(prev => [...prev, { role: "user", content: currentMessage }]);
  11.  
  12.         const processMessage = async () => {
  13.             try {
  14.                 const response = await fetch('/api/chat/send', {
  15.                     method: 'POST',
  16.                     headers: {
  17.                         'Content-Type': 'application/json',
  18.                     },
  19.                     body: JSON.stringify({
  20.                         model: selectedModel,
  21.                         message: currentMessage,
  22.                         chatId
  23.                     }),
  24.                 });
  25.  
  26.                 if (!response.ok) {
  27.                     const error = await response.json();
  28.                     throw new Error(error.error || 'Failed to send message');
  29.                 }
  30.  
  31.                 const data = await response.json();
  32.  
  33.                 if (data.content) {
  34.                     setMessages(prev => [...prev, {
  35.                         role: "assistant",
  36.                         content: data.content
  37.                     }]);
  38.                 }
  39.  
  40.             } catch (error) {
  41.                 console.error("Error in chat:", error);
  42.                 toast({
  43.                     title: "Error",
  44.                     description: error instanceof Error ? error.message : "Failed to send message",
  45.                     variant: "destructive",
  46.                 });
  47.  
  48.                 // Remove the user message if there was an error
  49.                 // setMessages(prev => prev.slice(0, -1));
  50.                 setMessages(prev => [...prev, { role: "assistant", content: "An error occurred. The page will refresh." }]);
  51.                 setTimeout(() => {
  52.                     window.location.reload();
  53.                 }, 3000); // Refresh after 3 seconds
  54.             } finally {
  55.                 setIsLoading(false);
  56.                 if (inputRef.current) {
  57.                     inputRef.current.focus();
  58.                 }
  59.             }
  60.         };
  61.  
  62.         processMessage();
  63.     }
  64.  
  65.  
  66.  
  67.  
  68. My /api/chat/send:
  69. import { verifyThreadOwnership } from "@/lib/dbFunctions";
  70. import { sendChatMessage } from "@/lib/llm";
  71. import { NextRequest, NextResponse } from "next/server";
  72.  
  73. export async function POST(req: NextRequest) {
  74.     try {
  75.         const { model, message, chatId } = await req.json();
  76.  
  77.         // Verify thread ownership
  78.         const isVerified = await verifyThreadOwnership(chatId);
  79.         if (!isVerified) {
  80.             return NextResponse.json(
  81.                 { error: "Unauthorized access to this chat thread" },
  82.                 { status: 401 }
  83.             );
  84.         }
  85.  
  86.         // Send message to OpenAI
  87.         const response = await sendChatMessage(model, message, chatId);
  88.  
  89.         return NextResponse.json(response);
  90.     } catch (error) {
  91.         console.error("Error in chat API:", error);
  92.         return NextResponse.json(
  93.             { error: error, content: error },
  94.             { status: 500 }
  95.         );
  96.     }
  97. }
  98.  
  99.  
  100.  
  101. The functions it's calling from the dbFunctions and llm
  102.  
  103. VerifyThreadOwnership:
  104. export async function verifyThreadOwnership(threadId: string): Promise<boolean> {
  105.    const { userId } = await auth();
  106.    await connectToDb();
  107.  
  108.    const user = await User.findOne({ userId: userId });
  109.    if (!user) {
  110.        throw new Error('User not found');
  111.    }
  112.  
  113.    const hasThread = user.chats.some((chat: chat) => chat.id === threadId);
  114.  
  115.    if (!hasThread) {
  116.        throw new Error('Unauthorized - Thread not found');
  117.    }
  118.  
  119.    return true;
  120. }
  121.  
  122.  
  123. export async function sendChatMessage(llmModel: string, messageContent: string, threadId: string): Promise<{ status: string, runId?: string, content?: string }> {
  124.    if (!(await hasEnoughTokens())) return { status: "error", content: "You don't have enough tokens" }
  125.  
  126.    try {
  127.        // Create message and start run
  128.        await client.beta.threads.messages.create(
  129.            threadId,
  130.            {
  131.                role: "user",
  132.                content: messageContent,
  133.            }
  134.        );
  135.  
  136.        const run = await client.beta.threads.runs.create(threadId, {
  137.            model: llmModel,
  138.            assistant_id: "asst_a2QluIujyYkVWXOJAYCTuKWh"
  139.        });
  140.  
  141.        // Wait for run to complete with timeout and polling
  142.        let runStatus;
  143.        do {
  144.            await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second between checks
  145.            runStatus = await client.beta.threads.runs.retrieve(threadId, run.id);
  146.        } while (runStatus.status === 'in_progress' || runStatus.status === 'queued');
  147.  
  148.        if (runStatus.status === 'completed') {
  149.            const messages = await client.beta.threads.messages.list(threadId);
  150.            const lastMessage = messages.data[0];
  151.  
  152.            await deductTokens(llmModel, runStatus.usage?.prompt_tokens ?? 0, runStatus.usage?.completion_tokens ?? 0);
  153.  
  154.            if (lastMessage.content[0].type === 'text') {
  155.                return { status: "completed", content: lastMessage.content[0].text.value };
  156.            }
  157.        }
  158.  
  159.        return { status: "error", content: "Run completed but no valid response found" };
  160.    } catch (error) {
  161.        console.error("Chat message error:", error);
  162.        return { status: "error", content: error instanceof Error ? error.message : 'An unexpected error occurred' };
  163.    }
  164. }
Advertisement
Add Comment
Please, Sign In to add comment