AI Chatbot v1

Run Settings
LanguageLua
Language Version
Run Command
--[[ AI CHATBOT v1 | In-Game AI Chat for Roblox Features: - Clean modern chat UI (draggable, resizable) - AI responses via Groq AI - Conversation memory (remembers context) - Smart fallback bot if API is down - Typing indicator animation - Chat history scroll - Mobile support - Press / to open, ESC to close Uses: Groq AI ]] ------------------------------------------------------------------------ -- CLEANUP ------------------------------------------------------------------------ pcall(function() for _, g in pairs(game:GetService("Players").LocalPlayer.PlayerGui:GetChildren()) do if g.Name == "AIChatGui" then g:Destroy() end end end) pcall(function() if _G._AIChatConns then for _, c in pairs(_G._AIChatConns) do pcall(function() c:Disconnect() end) end end end) _G._AIChatConns = {} local function conn(c) table.insert(_G._AIChatConns, c) return c end ------------------------------------------------------------------------ -- SERVICES ------------------------------------------------------------------------ local Players = game:GetService("Players") local UIS = game:GetService("UserInputService") local TS = game:GetService("TweenService") local HttpService = game:GetService("HttpService") local LP = Players.LocalPlayer ------------------------------------------------------------------------ -- CONFIG ------------------------------------------------------------------------ local CONFIG = { -- API endpoints (tried in order, first working one is used) apis = { { url = "https://api.groq.com/openai/v1/chat/completions", model = "llama-3.3-70b-versatile", key = "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" }, }, systemPrompt = "You are a friendly and helpful AI assistant chatting inside a Roblox game. Keep responses concise (under 200 words). Be fun, casual, and helpful. You can help with game tips, coding, homework, jokes, stories, or just chat. Use emojis occasionally. When generating code, always wrap it in ```lua code blocks so the user can execute it directly.", maxHistory = 20, -- messages to keep in context maxResponseLen = 500, -- chars } ------------------------------------------------------------------------ -- COLORS ------------------------------------------------------------------------ local C = { bg = Color3.fromRGB(15, 15, 25), chatBg = Color3.fromRGB(22, 22, 35), inputBg = Color3.fromRGB(30, 30, 48), userBub = Color3.fromRGB(75, 45, 180), aiBub = Color3.fromRGB(35, 38, 55), accent = Color3.fromRGB(130, 80, 255), accent2 = Color3.fromRGB(80, 200, 255), white = Color3.fromRGB(230, 230, 245), gray = Color3.fromRGB(140, 140, 165), dimgray = Color3.fromRGB(80, 80, 105), green = Color3.fromRGB(80, 255, 140), red = Color3.fromRGB(255, 80, 80), yellow = Color3.fromRGB(255, 220, 80), border = Color3.fromRGB(60, 40, 130), shadow = Color3.fromRGB(8, 8, 15), } ------------------------------------------------------------------------ -- STATE ------------------------------------------------------------------------ local chatOpen = false local isTyping = false local conversation = {} -- {role="user"/"assistant", content="..."} local messageFrames = {} local httpRequest = (syn and syn.request) or (http and http.request) or http_request or request or (fluxus and fluxus.request) or nil ------------------------------------------------------------------------ -- GUI SETUP ------------------------------------------------------------------------ local gui = Instance.new("ScreenGui") gui.Name = "AIChatGui" gui.ResetOnSpawn = false gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling gui.DisplayOrder = 100 gui.Parent = LP.PlayerGui -- Main container local main = Instance.new("Frame") main.Name = "Main" main.Size = UDim2.new(0, 380, 0, 500) main.Position = UDim2.new(0.5, -190, 0.5, -250) main.BackgroundColor3 = C.bg main.BorderSizePixel = 0 main.Visible = false main.Active = true main.Draggable = true main.ClipsDescendants = true main.Parent = gui Instance.new("UICorner", main).CornerRadius = UDim.new(0, 14) local mainStroke = Instance.new("UIStroke", main) mainStroke.Color = C.border mainStroke.Thickness = 2 mainStroke.Transparency = 0.3 -- Drop shadow (fake) local shadow = Instance.new("Frame") shadow.Size = UDim2.new(1, 16, 1, 16) shadow.Position = UDim2.new(0, -8, 0, -8) shadow.BackgroundColor3 = C.shadow shadow.BackgroundTransparency = 0.6 shadow.BorderSizePixel = 0 shadow.ZIndex = -1 shadow.Parent = main Instance.new("UICorner", shadow).CornerRadius = UDim.new(0, 18) ------------------------------------------------------------------------ -- HEADER ------------------------------------------------------------------------ local header = Instance.new("Frame") header.Size = UDim2.new(1, 0, 0, 50) header.BackgroundColor3 = Color3.fromRGB(25, 20, 45) header.BorderSizePixel = 0 header.ZIndex = 5 header.Parent = main Instance.new("UICorner", header).CornerRadius = UDim.new(0, 14) local headerFix = Instance.new("Frame") headerFix.Size = UDim2.new(1, 0, 0, 14) headerFix.Position = UDim2.new(0, 0, 1, -14) headerFix.BackgroundColor3 = Color3.fromRGB(25, 20, 45) headerFix.BorderSizePixel = 0 headerFix.ZIndex = 5 headerFix.Parent = header -- AI icon (circle) local aiIcon = Instance.new("Frame") aiIcon.Size = UDim2.new(0, 32, 0, 32) aiIcon.Position = UDim2.new(0, 12, 0.5, -16) aiIcon.BackgroundColor3 = C.accent aiIcon.BorderSizePixel = 0 aiIcon.ZIndex = 6 aiIcon.Parent = header Instance.new("UICorner", aiIcon).CornerRadius = UDim.new(1, 0) local aiIconTxt = Instance.new("TextLabel") aiIconTxt.Size = UDim2.new(1, 0, 1, 0) aiIconTxt.BackgroundTransparency = 1 aiIconTxt.Text = "AI" aiIconTxt.TextColor3 = C.white aiIconTxt.Font = Enum.Font.GothamBold aiIconTxt.TextSize = 13 aiIconTxt.ZIndex = 7 aiIconTxt.Parent = aiIcon -- Title local titleLbl = Instance.new("TextLabel") titleLbl.Size = UDim2.new(0, 200, 0, 20) titleLbl.Position = UDim2.new(0, 52, 0, 7) titleLbl.BackgroundTransparency = 1 titleLbl.Text = "🤖 AI Chat" titleLbl.TextColor3 = C.white titleLbl.Font = Enum.Font.GothamBold titleLbl.TextSize = 16 titleLbl.TextXAlignment = Enum.TextXAlignment.Left titleLbl.ZIndex = 6 titleLbl.Parent = header -- Status local statusLbl = Instance.new("TextLabel") statusLbl.Size = UDim2.new(0, 200, 0, 14) statusLbl.Position = UDim2.new(0, 52, 0, 28) statusLbl.BackgroundTransparency = 1 statusLbl.Text = "Online • Type a message" statusLbl.TextColor3 = C.green statusLbl.Font = Enum.Font.Gotham statusLbl.TextSize = 11 statusLbl.TextXAlignment = Enum.TextXAlignment.Left statusLbl.ZIndex = 6 statusLbl.Parent = header -- Close button local closeBtn = Instance.new("TextButton") closeBtn.Size = UDim2.new(0, 36, 0, 36) closeBtn.Position = UDim2.new(1, -44, 0.5, -18) closeBtn.BackgroundColor3 = C.red closeBtn.BackgroundTransparency = 0.7 closeBtn.BorderSizePixel = 0 closeBtn.Text = "✕" closeBtn.TextColor3 = C.white closeBtn.Font = Enum.Font.GothamBold closeBtn.TextSize = 16 closeBtn.ZIndex = 6 closeBtn.AutoButtonColor = false closeBtn.Parent = header Instance.new("UICorner", closeBtn).CornerRadius = UDim.new(0, 8) closeBtn.MouseEnter:Connect(function() TS:Create(closeBtn, TweenInfo.new(0.15), {BackgroundTransparency = 0.3}):Play() end) closeBtn.MouseLeave:Connect(function() TS:Create(closeBtn, TweenInfo.new(0.15), {BackgroundTransparency = 0.7}):Play() end) -- Clear button local clearBtn = Instance.new("TextButton") clearBtn.Size = UDim2.new(0, 36, 0, 36) clearBtn.Position = UDim2.new(1, -84, 0.5, -18) clearBtn.BackgroundColor3 = C.dimgray clearBtn.BackgroundTransparency = 0.7 clearBtn.BorderSizePixel = 0 clearBtn.Text = "🗑" clearBtn.TextColor3 = C.white clearBtn.Font = Enum.Font.GothamBold clearBtn.TextSize = 14 clearBtn.ZIndex = 6 clearBtn.AutoButtonColor = false clearBtn.Parent = header Instance.new("UICorner", clearBtn).CornerRadius = UDim.new(0, 8) ------------------------------------------------------------------------ -- CHAT AREA (scrolling) ------------------------------------------------------------------------ local chatArea = Instance.new("ScrollingFrame") chatArea.Size = UDim2.new(1, -16, 1, -114) chatArea.Position = UDim2.new(0, 8, 0, 54) chatArea.BackgroundTransparency = 1 chatArea.BorderSizePixel = 0 chatArea.ScrollBarThickness = 3 chatArea.ScrollBarImageColor3 = C.accent chatArea.CanvasSize = UDim2.new(0, 0, 0, 0) chatArea.AutomaticCanvasSize = Enum.AutomaticSize.Y chatArea.ScrollingDirection = Enum.ScrollingDirection.Y chatArea.Parent = main local chatLayout = Instance.new("UIListLayout", chatArea) chatLayout.Padding = UDim.new(0, 8) chatLayout.SortOrder = Enum.SortOrder.LayoutOrder chatLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center local chatPadding = Instance.new("UIPadding", chatArea) chatPadding.PaddingTop = UDim.new(0, 8) chatPadding.PaddingBottom = UDim.new(0, 8) ------------------------------------------------------------------------ -- INPUT BAR ------------------------------------------------------------------------ local inputBar = Instance.new("Frame") inputBar.Size = UDim2.new(1, -16, 0, 48) inputBar.Position = UDim2.new(0, 8, 1, -56) inputBar.BackgroundColor3 = C.inputBg inputBar.BorderSizePixel = 0 inputBar.ZIndex = 5 inputBar.Parent = main Instance.new("UICorner", inputBar).CornerRadius = UDim.new(0, 12) Instance.new("UIStroke", inputBar).Color = C.border local inputBox = Instance.new("TextBox") inputBox.Size = UDim2.new(1, -56, 1, -12) inputBox.Position = UDim2.new(0, 14, 0, 6) inputBox.BackgroundTransparency = 1 inputBox.Text = "" inputBox.PlaceholderText = "Type a message..." inputBox.PlaceholderColor3 = C.dimgray inputBox.TextColor3 = C.white inputBox.Font = Enum.Font.Gotham inputBox.TextSize = 14 inputBox.TextXAlignment = Enum.TextXAlignment.Left inputBox.ClearTextOnFocus = false inputBox.ZIndex = 6 inputBox.Parent = inputBar local sendBtn = Instance.new("TextButton") sendBtn.Size = UDim2.new(0, 36, 0, 36) sendBtn.Position = UDim2.new(1, -42, 0.5, -18) sendBtn.BackgroundColor3 = C.accent sendBtn.BorderSizePixel = 0 sendBtn.Text = "📨" sendBtn.TextColor3 = C.white sendBtn.Font = Enum.Font.GothamBold sendBtn.TextSize = 18 sendBtn.ZIndex = 6 sendBtn.AutoButtonColor = false sendBtn.Parent = inputBar Instance.new("UICorner", sendBtn).CornerRadius = UDim.new(0, 10) ------------------------------------------------------------------------ -- MESSAGE BUBBLE FACTORY ------------------------------------------------------------------------ local msgOrder = 0 local function scrollToBottom() task.defer(function() task.wait(0.05) chatArea.CanvasPosition = Vector2.new(0, chatArea.AbsoluteCanvasSize.Y) end) end local function addMessage(text, role, animate) msgOrder = msgOrder + 1 local isUser = (role == "user") -- Container local container = Instance.new("Frame") container.Size = UDim2.new(1, -8, 0, 0) container.AutomaticSize = Enum.AutomaticSize.Y container.BackgroundTransparency = 1 container.LayoutOrder = msgOrder container.Parent = chatArea -- Bubble local bubble = Instance.new("Frame") bubble.Size = UDim2.new(0.85, 0, 0, 0) bubble.AutomaticSize = Enum.AutomaticSize.Y bubble.Position = isUser and UDim2.new(0.15, 0, 0, 0) or UDim2.new(0, 0, 0, 0) bubble.BackgroundColor3 = isUser and C.userBub or C.aiBub bubble.BorderSizePixel = 0 bubble.Parent = container Instance.new("UICorner", bubble).CornerRadius = UDim.new(0, 12) local bLayout = Instance.new("UIListLayout", bubble) bLayout.SortOrder = Enum.SortOrder.LayoutOrder bLayout.Padding = UDim.new(0, 4) local padding = Instance.new("UIPadding", bubble) padding.PaddingTop = UDim.new(0, 10) padding.PaddingBottom = UDim.new(0, 10) padding.PaddingLeft = UDim.new(0, 12) padding.PaddingRight = UDim.new(0, 12) -- Role label with icons local roleLbl = Instance.new("TextLabel") roleLbl.Size = UDim2.new(1, 0, 0, 16) roleLbl.BackgroundTransparency = 1 roleLbl.Text = isUser and "👤 You" or "🤖 AI Assistant" roleLbl.TextColor3 = isUser and C.accent2 or C.green roleLbl.Font = Enum.Font.GothamBold roleLbl.TextSize = 11 roleLbl.TextXAlignment = isUser and Enum.TextXAlignment.Right or Enum.TextXAlignment.Left roleLbl.LayoutOrder = 1 roleLbl.Parent = bubble -- Message text local msgLbl = Instance.new("TextLabel") msgLbl.Name = "MsgLabel" msgLbl.Size = UDim2.new(1, 0, 0, 0) msgLbl.AutomaticSize = Enum.AutomaticSize.Y msgLbl.BackgroundTransparency = 1 msgLbl.Text = text msgLbl.TextColor3 = C.white msgLbl.Font = Enum.Font.Gotham msgLbl.TextSize = 13 msgLbl.TextWrapped = true msgLbl.TextXAlignment = Enum.TextXAlignment.Left msgLbl.RichText = true msgLbl.LayoutOrder = 2 msgLbl.Parent = bubble -- Animation if animate then bubble.BackgroundTransparency = 1 msgLbl.TextTransparency = 1 roleLbl.TextTransparency = 1 TS:Create(bubble, TweenInfo.new(0.25, Enum.EasingStyle.Quad), {BackgroundTransparency = 0}):Play() TS:Create(msgLbl, TweenInfo.new(0.25, Enum.EasingStyle.Quad), {TextTransparency = 0}):Play() TS:Create(roleLbl, TweenInfo.new(0.25, Enum.EasingStyle.Quad), {TextTransparency = 0}):Play() end table.insert(messageFrames, container) scrollToBottom() return msgLbl, bubble -- return both for code box rendering end -- Typing indicator local typingContainer = nil local typingDots = {} local function showTyping() if typingContainer then return end msgOrder = msgOrder + 1 typingContainer = Instance.new("Frame") typingContainer.Size = UDim2.new(1, -8, 0, 36) typingContainer.BackgroundTransparency = 1 typingContainer.LayoutOrder = msgOrder + 9999 typingContainer.Parent = chatArea local bubble = Instance.new("Frame") bubble.Size = UDim2.new(0, 80, 0, 32) bubble.BackgroundColor3 = C.aiBub bubble.BorderSizePixel = 0 bubble.Parent = typingContainer Instance.new("UICorner", bubble).CornerRadius = UDim.new(0, 12) for i = 1, 3 do local dot = Instance.new("Frame") dot.Size = UDim2.new(0, 8, 0, 8) dot.Position = UDim2.new(0, 16 + (i - 1) * 18, 0.5, -4) dot.BackgroundColor3 = C.gray dot.BorderSizePixel = 0 dot.Parent = bubble Instance.new("UICorner", dot).CornerRadius = UDim.new(1, 0) table.insert(typingDots, dot) end -- Animate dots task.spawn(function() local idx = 0 while typingContainer and typingContainer.Parent do idx = idx + 1 for i, dot in pairs(typingDots) do local active = ((idx + i) % 3 == 0) TS:Create(dot, TweenInfo.new(0.3), { BackgroundColor3 = active and C.accent or C.gray, Size = active and UDim2.new(0, 10, 0, 10) or UDim2.new(0, 8, 0, 8), Position = active and UDim2.new(0, 15 + (i-1)*18, 0.5, -5) or UDim2.new(0, 16 + (i-1)*18, 0.5, -4), }):Play() end task.wait(0.4) end end) scrollToBottom() end local function hideTyping() if typingContainer then typingContainer:Destroy() typingContainer = nil typingDots = {} end end ------------------------------------------------------------------------ -- SMART FALLBACK BOT (when API unavailable) ------------------------------------------------------------------------ local function fallbackResponse(msg) local low = msg:lower() -- Greetings if low:find("^h[ie]") or low:find("hello") or low:find("hey") or low:find("sup") or low:find("yo ") or low == "yo" then local greetings = { "Hey there! 👋 What's up?", "Hello! How's it going? 😄", "Hey! What can I help you with?", "Yo! What's on your mind? 🎮", "Hi there! Ready to chat! ✨", } return greetings[math.random(#greetings)] end -- How are you if low:find("how are you") or low:find("how r u") or low:find("hru") or low:find("wyd") then local responses = { "I'm doing great! Just vibing in Roblox 😎 How about you?", "Living my best AI life! What about you? 🤖", "Pretty good! Ready to help with whatever you need! ✨", } return responses[math.random(#responses)] end -- Jokes if low:find("joke") or low:find("funny") or low:find("laugh") then local jokes = { "Why do programmers prefer dark mode? Because light attracts bugs! 🐛😂", "Why did the Roblox player cross the road? To get to the other server! 😄", "What's a noob's favorite key? The respawn button! 💀😂", "Why don't scientists trust atoms? Because they make up everything! ⚛️😂", "I told my computer I needed a break... now it won't stop sending me Kit-Kat ads 🍫", "Why was the JavaScript developer sad? Because he didn't Node how to Express himself! 💻", "What do you call a fake noodle? An impasta! 🍝😂", "Why did the scarecrow win an award? He was outstanding in his field! 🌾", } return jokes[math.random(#jokes)] end -- Help if low:find("help") or low:find("what can you") or low:find("what do you") then return "I can help with lots of things! 🎯\n\n• Chat & have fun conversations\n• Tell jokes 😂\n• Help with game tips\n• Answer questions\n• Help with homework/coding\n• Tell stories\n• Play word games\n\nJust ask me anything! (Note: I'm running in fallback mode since the AI API isn't connected. Add your API key for full AI responses!)" end -- Math if low:find("what is %d") or low:find("calculate") or low:find("%d+%s*[%+%-%*/]%s*%d+") then local expr = low:match("(%d+%s*[%+%-%*/]%s*%d+)") if expr then local fn = loadstring("return " .. expr) if fn then local ok, result = pcall(fn) if ok then return "🧮 " .. expr .. " = **" .. tostring(result) .. "**" end end end return "I can do basic math! Try something like '2 + 2' or '15 * 3' 🧮" end -- Games if low:find("game") or low:find("roblox") or low:find("play") then local responses = { "Roblox is awesome! What game are you playing right now? 🎮", "There are so many great games on Roblox! Some favorites are Blox Fruits, Arsenal, and Adopt Me! What do you like? 🕹️", "Gaming is life! 🎮 Are you looking for game recommendations or tips?", } return responses[math.random(#responses)] end -- Compliments if low:find("thank") or low:find("cool") or low:find("awesome") or low:find("nice") or low:find("good bot") then local responses = { "Aww thanks! You're awesome too! 😊✨", "Glad I could help! 🎉", "You're too kind! 💜", "Thanks! That means a lot coming from you! 😄", } return responses[math.random(#responses)] end -- Story if low:find("story") or low:find("tell me") then return "📖 Once upon a time, in a blocky world made of cubes, there lived a brave Robloxian named " .. LP.Name .. ". They ventured through dangerous obbies, battled fierce noobs, and collected legendary items. One day, they discovered a mysterious portal that led to... well, that's a story for another time! 😉✨" end -- Who are you if low:find("who are you") or low:find("what are you") or low:find("your name") then return "I'm an AI chatbot running right inside your Roblox game! 🤖✨ I'm here to chat, help out, tell jokes, or just hang out. Think of me as your in-game AI buddy!" end -- Bye if low:find("bye") or low:find("gtg") or low:find("gotta go") or low:find("cya") or low:find("see ya") then local responses = { "See ya later! Have fun! 👋😄", "Bye! Come chat anytime! ✌️", "Later! Stay awesome! 🎮✨", } return responses[math.random(#responses)] end -- Default responses local defaults = { "That's interesting! Tell me more about that 🤔", "Hmm, I'm thinking about that... Could you elaborate? 💭", "Cool! What else is on your mind? 😊", "I hear you! Anything else you want to chat about? 🎯", "That's a great point! 👍 What do you think about it?", "Interesting! I'm in fallback mode right now, but I'm still here to chat! Add an API key in the script config for full AI responses 🤖", "I love chatting! Even without the AI API connected, I can still hang out with you 😄", } return defaults[math.random(#defaults)] end ------------------------------------------------------------------------ -- API CALL ------------------------------------------------------------------------ local usingAPI = false local apiName = "Fallback" local function callAI(userMsg) -- Build messages array local messages = { {role = "system", content = CONFIG.systemPrompt}, } -- Add conversation history local startIdx = math.max(1, #conversation - CONFIG.maxHistory + 1) for i = startIdx, #conversation do table.insert(messages, conversation[i]) end -- Add current message table.insert(messages, {role = "user", content = userMsg}) -- Try each API if httpRequest then for _, api in pairs(CONFIG.apis) do do -- try each API local ok, result = pcall(function() local body = HttpService:JSONEncode({ model = api.model, messages = messages, max_tokens = 300, temperature = 0.8, }) local response = httpRequest({ Url = api.url, Method = "POST", Headers = { ["Content-Type"] = "application/json", ["Authorization"] = "Bearer " .. api.key, }, Body = body, }) if response.StatusCode == 200 then local data = HttpService:JSONDecode(response.Body) if data.choices and data.choices[1] then usingAPI = true apiName = api.model return data.choices[1].message.content end end return nil end) if ok and result then return result end end end end -- Fallback usingAPI = false apiName = "Fallback" return fallbackResponse(userMsg) end ------------------------------------------------------------------------ -- SEND MESSAGE ------------------------------------------------------------------------ local function sendMessage() local text = inputBox.Text if text == "" or isTyping then return end text = text:sub(1, 500) -- limit inputBox.Text = "" -- Add user message table.insert(conversation, {role = "user", content = text}) addMessage(text, "user", true) -- Show typing isTyping = true statusLbl.Text = "🧠 AI is thinking..." statusLbl.TextColor3 = C.yellow showTyping() -- Get response async task.spawn(function() local response = callAI(text) -- Trim response if #response > CONFIG.maxResponseLen then response = response:sub(1, CONFIG.maxResponseLen) .. "..." end -- Store in conversation table.insert(conversation, {role = "assistant", content = response}) -- Trim conversation history while #conversation > CONFIG.maxHistory * 2 do table.remove(conversation, 1) end hideTyping() -- Typewriter effect local msgLbl, aiBubble = addMessage("", "assistant", true) local displayed = "" for i = 1, #response do displayed = response:sub(1, i) msgLbl.Text = displayed scrollToBottom() -- Variable speed for natural feel local ch = response:sub(i, i) if ch == "." or ch == "!" or ch == "?" then task.wait(0.04) elseif ch == "," or ch == ":" then task.wait(0.02) elseif ch == "\n" then task.wait(0.03) else task.wait(0.008) end end -- Parse and render code blocks in a styled box with execute button local function renderCodeBlocks(fullText, parentBubble) -- Find code blocks: ```...``` local codeBlocks = {} for codeContent in fullText:gmatch("```(.-)```") do table.insert(codeBlocks, codeContent) end if #codeBlocks == 0 then return end for _, rawCode in pairs(codeBlocks) do -- Clean language tag local cleanCode = rawCode:gsub("^%s*[Ll]ua[u]?%s*\n", ""):gsub("^%s*\n", ""):gsub("\n%s*$", "") -- Code box container local codeBox = Instance.new("Frame") codeBox.Size = UDim2.new(1, 0, 0, 0) codeBox.AutomaticSize = Enum.AutomaticSize.Y codeBox.BackgroundColor3 = Color3.fromRGB(15, 15, 25) codeBox.BorderSizePixel = 0 codeBox.LayoutOrder = 3 codeBox.Parent = parentBubble Instance.new("UICorner", codeBox).CornerRadius = UDim.new(0, 8) local codeStroke = Instance.new("UIStroke", codeBox) codeStroke.Color = Color3.fromRGB(80, 60, 160) codeStroke.Thickness = 1 codeStroke.Transparency = 0.5 local codePad = Instance.new("UIPadding", codeBox) codePad.PaddingTop = UDim.new(0, 6) codePad.PaddingBottom = UDim.new(0, 6) codePad.PaddingLeft = UDim.new(0, 10) codePad.PaddingRight = UDim.new(0, 10) local codeLayout = Instance.new("UIListLayout", codeBox) codeLayout.SortOrder = Enum.SortOrder.LayoutOrder codeLayout.Padding = UDim.new(0, 4) -- Code header with icon local codeHeader = Instance.new("TextLabel") codeHeader.Size = UDim2.new(1, 0, 0, 16) codeHeader.BackgroundTransparency = 1 codeHeader.Text = "📜 Code" codeHeader.TextColor3 = Color3.fromRGB(160, 140, 255) codeHeader.Font = Enum.Font.GothamBold codeHeader.TextSize = 10 codeHeader.TextXAlignment = Enum.TextXAlignment.Left codeHeader.LayoutOrder = 1 codeHeader.Parent = codeBox -- Code text (monospace style) local codeLbl = Instance.new("TextLabel") codeLbl.Size = UDim2.new(1, 0, 0, 0) codeLbl.AutomaticSize = Enum.AutomaticSize.Y codeLbl.BackgroundTransparency = 1 codeLbl.Text = cleanCode codeLbl.TextColor3 = Color3.fromRGB(200, 220, 255) codeLbl.Font = Enum.Font.Code codeLbl.TextSize = 11 codeLbl.TextWrapped = true codeLbl.TextXAlignment = Enum.TextXAlignment.Left codeLbl.LayoutOrder = 2 codeLbl.Parent = codeBox -- Button row local btnRow = Instance.new("Frame") btnRow.Size = UDim2.new(1, 0, 0, 30) btnRow.BackgroundTransparency = 1 btnRow.LayoutOrder = 3 btnRow.Parent = codeBox local btnLayout = Instance.new("UIListLayout", btnRow) btnLayout.FillDirection = Enum.FillDirection.Horizontal btnLayout.SortOrder = Enum.SortOrder.LayoutOrder btnLayout.Padding = UDim.new(0, 6) -- Execute button local execBtn = Instance.new("TextButton") execBtn.Size = UDim2.new(0, 130, 0, 28) execBtn.BackgroundColor3 = Color3.fromRGB(40, 167, 69) execBtn.BorderSizePixel = 0 execBtn.Text = "▶️ Execute Code" execBtn.TextColor3 = Color3.new(1, 1, 1) execBtn.Font = Enum.Font.GothamBold execBtn.TextSize = 11 execBtn.LayoutOrder = 1 execBtn.Parent = btnRow Instance.new("UICorner", execBtn).CornerRadius = UDim.new(0, 6) -- Copy button local copyBtn = Instance.new("TextButton") copyBtn.Size = UDim2.new(0, 90, 0, 28) copyBtn.BackgroundColor3 = Color3.fromRGB(60, 50, 120) copyBtn.BorderSizePixel = 0 copyBtn.Text = "📋 Copy" copyBtn.TextColor3 = Color3.new(1, 1, 1) copyBtn.Font = Enum.Font.GothamBold copyBtn.TextSize = 11 copyBtn.LayoutOrder = 2 copyBtn.Parent = btnRow Instance.new("UICorner", copyBtn).CornerRadius = UDim.new(0, 6) -- Execute handler conn(execBtn.MouseButton1Click:Connect(function() execBtn.Text = "⏳ Running..." execBtn.BackgroundColor3 = Color3.fromRGB(255, 193, 7) execBtn.TextColor3 = Color3.fromRGB(30, 30, 30) local ok, err = pcall(function() local fn = loadstring(cleanCode) if fn then fn() else error("Failed to compile") end end) if ok then execBtn.Text = "✅ Success!" execBtn.BackgroundColor3 = Color3.fromRGB(40, 167, 69) execBtn.TextColor3 = Color3.new(1, 1, 1) else execBtn.Text = "❌ Error" execBtn.BackgroundColor3 = Color3.fromRGB(220, 53, 69) execBtn.TextColor3 = Color3.new(1, 1, 1) addMessage("⚠️ Error: " .. tostring(err), "assistant", true) end task.delay(3, function() pcall(function() execBtn.Text = "▶️ Execute Code" execBtn.BackgroundColor3 = Color3.fromRGB(40, 167, 69) end) end) end)) -- Copy handler conn(copyBtn.MouseButton1Click:Connect(function() pcall(function() setclipboard(cleanCode) end) copyBtn.Text = "✅ Copied!" task.delay(2, function() pcall(function() copyBtn.Text = "📋 Copy" end) end) end)) end scrollToBottom() end renderCodeBlocks(response, aiBubble) isTyping = false local modeText = usingAPI and ("Online • " .. apiName) or "🟡 Online • Fallback Mode" statusLbl.Text = modeText statusLbl.TextColor3 = C.green end) end ------------------------------------------------------------------------ -- WELCOME MESSAGE ------------------------------------------------------------------------ local function showWelcome() addMessage("Hey " .. LP.Name .. "! 👋 I'm your AI chatbot!\n\nYou can ask me anything — questions, jokes, help with stuff, or just chat!\n\n💡 <b>Tip:</b> Add your API key in the script config for full AI responses. Without it, I use a smart fallback bot.\n\n<b>Press / to open • ESC to close</b>", "assistant", false) end ------------------------------------------------------------------------ -- CLEAR CHAT ------------------------------------------------------------------------ local function clearChat() for _, frame in pairs(messageFrames) do pcall(function() frame:Destroy() end) end messageFrames = {} conversation = {} msgOrder = 0 hideTyping() showWelcome() end ------------------------------------------------------------------------ -- BUTTON CONNECTIONS ------------------------------------------------------------------------ closeBtn.MouseButton1Click:Connect(function() chatOpen = false main.Visible = false end) clearBtn.MouseButton1Click:Connect(function() clearChat() end) sendBtn.MouseButton1Click:Connect(function() sendMessage() end) inputBox.FocusLost:Connect(function(enter) if enter then sendMessage() end end) -- Send button hover sendBtn.MouseEnter:Connect(function() TS:Create(sendBtn, TweenInfo.new(0.15), {BackgroundColor3 = Color3.fromRGB(150, 100, 255)}):Play() end) sendBtn.MouseLeave:Connect(function() TS:Create(sendBtn, TweenInfo.new(0.15), {BackgroundColor3 = C.accent}):Play() end) ------------------------------------------------------------------------ -- OPEN/CLOSE HOTKEYS ------------------------------------------------------------------------ conn(UIS.InputBegan:Connect(function(inp, gpe) if inp.KeyCode == Enum.KeyCode.Escape and chatOpen then chatOpen = false main.Visible = false return end if gpe then return end if inp.KeyCode == Enum.KeyCode.Slash then chatOpen = not chatOpen main.Visible = chatOpen if chatOpen then task.defer(function() inputBox:CaptureFocus() end) end end end)) ------------------------------------------------------------------------ -- MOBILE OPEN BUTTON ------------------------------------------------------------------------ local isMobile = UIS.TouchEnabled and not UIS.KeyboardEnabled local openBtn = Instance.new("TextButton") openBtn.Size = UDim2.new(0, 50, 0, 50) openBtn.Position = isMobile and UDim2.new(1, -60, 0.4, 0) or UDim2.new(1, -60, 0, 10) openBtn.BackgroundColor3 = C.accent openBtn.BackgroundTransparency = 0.2 openBtn.BorderSizePixel = 0 openBtn.Text = "🤖💬" openBtn.TextSize = 24 openBtn.Font = Enum.Font.GothamBold openBtn.TextColor3 = C.white openBtn.Active = true openBtn.Draggable = true openBtn.Parent = gui Instance.new("UICorner", openBtn).CornerRadius = UDim.new(0, 25) Instance.new("UIStroke", openBtn).Color = C.border -- Notification dot local notifDot = Instance.new("Frame") notifDot.Size = UDim2.new(0, 14, 0, 14) notifDot.Position = UDim2.new(1, -6, 0, -4) notifDot.BackgroundColor3 = C.green notifDot.BorderSizePixel = 0 notifDot.Parent = openBtn Instance.new("UICorner", notifDot).CornerRadius = UDim.new(1, 0) openBtn.MouseButton1Click:Connect(function() chatOpen = not chatOpen main.Visible = chatOpen if chatOpen then notifDot.Visible = false if not isMobile then task.defer(function() inputBox:CaptureFocus() end) end end end) -- Pulse animation on open button task.spawn(function() while task.wait(2) do if not chatOpen then TS:Create(openBtn, TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), { BackgroundTransparency = 0.5 }):Play() task.wait(0.5) TS:Create(openBtn, TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), { BackgroundTransparency = 0.2 }):Play() end end end) ------------------------------------------------------------------------ -- ANTI-AFK ------------------------------------------------------------------------ do local vu = game:GetService("VirtualUser") conn(LP.Idled:Connect(function() vu:CaptureController() vu:ClickButton2(Vector2.new()) end)) end ------------------------------------------------------------------------ -- INIT ------------------------------------------------------------------------ showWelcome() print("=== AI CHATBOT v1 ===") print(" Press / to open chat") print(" Press ESC to close") print(" Or tap the 💬 button") if httpRequest then print(" HTTP detected! Add API keys in config for full AI.") else print(" No HTTP function found. Using smart fallback bot.") end print("=====================")
Editor Settings
Theme
Key bindings
Full width
Lines