import { useState, useCallback, memo } from 'react'; import { Button } from '@/components/ui/button'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Textarea } from '@/components/ui/textarea'; import { Sparkle, PaperPlaneRight } from '@phosphor-icons/react'; import { toast } from 'sonner'; import { captureError } from '@/lib/sentry'; interface Message { role: 'user' | 'assistant'; content: string; } interface AIChatProps { currentCode: string; } export function AIChat({ currentCode }: AIChatProps) { const [messages, setMessages] = useState([ { role: 'assistant', content: 'Hi! I\'m your AI assistant for Roblox Lua development. Ask me anything about your code, Roblox scripting, or game development!', }, ]); const [input, setInput] = useState(''); const [isLoading, setIsLoading] = useState(false); const handleSend = useCallback(async () => { if (!input.trim() || isLoading) return; const userMessage = input.trim(); setInput(''); setMessages((prev) => [...prev, { role: 'user', content: userMessage }]); setIsLoading(true); try { if (typeof window === 'undefined' || !window.spark?.llm) { throw new Error('AI service is not available'); } // Context-aware prompt: include active code, file name, and platform const promptText = `You are an expert Roblox Lua developer and code assistant.\n\nUser's active code:\n\n\`\`\`lua\n${currentCode}\n\`\`\`\n\nUser question: ${userMessage}\n\nIf the user asks for code completion, suggest the next line(s) of code.\nIf the user asks for an explanation, explain the code in simple terms.\nIf the user asks for platform-specific help, provide Roblox Lua answers.\n\nRespond with concise, friendly, and actionable advice. Include code examples inline when relevant.`; const response = await window.spark.llm(promptText, 'gpt-4o-mini'); // If the response contains code, show it in a highlighted block const codeMatch = response.match(/```lua([\s\S]*?)```/); if (codeMatch) { setMessages((prev) => [ ...prev, { role: 'assistant', content: response.replace(/```lua([\s\S]*?)```/, '') }, { role: 'assistant', content: `
${codeMatch[1].trim()}
` }, ]); } else { setMessages((prev) => [...prev, { role: 'assistant', content: response }]); } } catch (error) { console.error('AI chat error:', error); captureError(error as Error, { context: 'ai_chat', userMessage, codeLength: currentCode.length }); toast.error('Failed to get AI response. Please try again.'); setMessages((prev) => [...prev, { role: 'assistant', content: 'Sorry, I encountered an error. Please try asking again or check your connection.' }]); } finally { setIsLoading(false); } }, [input, isLoading, currentCode]); const handleKeyDown = useCallback((e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); } }, [handleSend]); return (
{messages.map((message, index) => (
{message.content.startsWith(' ) : (

{message.content}

)}
))} {isLoading && (
)}