
Key RequiredUniversal

-- ====================================================================
-- Gemini AI Mobile Client (Fixed Inputs, Layers, & Dropdown)
-- ====================================================================
local CoreGui = game:GetService("CoreGui")
local HttpService = game:GetService("HttpService")
local UserInputService = game:GetService("UserInputService")
local TextService = game:GetService("TextService")
local Players = game:GetService("Players")
-- Universal HTTP resolver
local httpRequest = (syn and syn.request) or (http and http.request) or http_request or request
if not httpRequest then
error("Gemini Script Error: Your executor does not support HTTP requests.")
end
local ConversationHistory = {}
-- Active Models Map
local ModelsList = {
{ Name = "Gemini 3.6 Flash", ID = "gemini-3.6-flash" },
{ Name = "Gemini 3.5 Flash", ID = "gemini-3.5-flash" },
{ Name = "Gemini 2.5 Flash", ID = "gemini-2.5-flash" },
{ Name = "Gemini Flash Lite", ID = "gemini-2.5-flash-lite" }
}
local SelectedModelID = "gemini-3.6-flash"
-- Setup ScreenGui
local LocalPlayer = Players.LocalPlayer or Players:GetPropertyChangedSignal("LocalPlayer"):Wait()
local ScreenGui = Instance.new("ScreenGui")
ScreenGui.Name = "GeminiClientUI"
ScreenGui.ResetOnSpawn = false
ScreenGui.DisplayOrder = 9999
ScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
pcall(function() ScreenGui.Parent = LocalPlayer:WaitForChild("PlayerGui") end)
if not ScreenGui.Parent then ScreenGui.Parent = CoreGui end
-- Main UI Frame
local MainFrame = Instance.new("Frame")
MainFrame.Name = "MainFrame"
MainFrame.Size = UDim2.new(0, 320, 0, 420)
MainFrame.Position = UDim2.new(0.5, -160, 0.4, -210)
MainFrame.BackgroundColor3 = Color3.fromRGB(24, 25, 28)
MainFrame.BorderSizePixel = 0
MainFrame.ClipsDescendants = false -- Set to false so dropdown doesn't get clipped
MainFrame.Active = true
MainFrame.ZIndex = 1
MainFrame.Parent = ScreenGui
local MainCorner = Instance.new("UICorner")
MainCorner.CornerRadius = UDim.new(0, 12)
MainCorner.Parent = MainFrame
-- Header (Drag Handle)
local Header = Instance.new("Frame")
Header.Size = UDim2.new(1, 0, 0, 40)
Header.BackgroundColor3 = Color3.fromRGB(18, 19, 22)
Header.BorderSizePixel = 0
Header.Active = true
Header.ZIndex = 2
Header.Parent = MainFrame
local Title = Instance.new("TextLabel")
Title.Size = UDim2.new(1, -50, 1, 0)
Title.Position = UDim2.new(0, 12, 0, 0)
Title.BackgroundTransparency = 1
Title.Text = "Gemini AI"
Title.TextColor3 = Color3.fromRGB(138, 180, 248)
Title.TextSize = 15
Title.Font = Enum.Font.GothamBold
Title.TextXAlignment = Enum.TextXAlignment.Left
Title.ZIndex = 3
Title.Parent = Header
local CloseBtn = Instance.new("TextButton")
CloseBtn.Size = UDim2.new(0, 30, 0, 30)
CloseBtn.Position = UDim2.new(1, -35, 0, 5)
CloseBtn.BackgroundColor3 = Color3.fromRGB(35, 38, 42)
CloseBtn.Text = "✕"
CloseBtn.TextColor3 = Color3.fromRGB(200, 200, 200)
CloseBtn.TextSize = 13
CloseBtn.Font = Enum.Font.GothamBold
CloseBtn.Active = true
CloseBtn.ZIndex = 4
CloseBtn.Parent = Header
local CloseCorner = Instance.new("UICorner")
CloseCorner.CornerRadius = UDim.new(0, 6)
CloseCorner.Parent = CloseBtn
-- API Key Input Bar
local KeyFrame = Instance.new("Frame")
KeyFrame.Size = UDim2.new(1, -20, 0, 32)
KeyFrame.Position = UDim2.new(0, 10, 0, 46)
KeyFrame.BackgroundColor3 = Color3.fromRGB(32, 33, 37)
KeyFrame.BorderSizePixel = 0
KeyFrame.ZIndex = 2
KeyFrame.Parent = MainFrame
local KeyCorner = Instance.new("UICorner")
KeyCorner.CornerRadius = UDim.new(0, 6)
KeyCorner.Parent = KeyFrame
local KeyInput = Instance.new("TextBox")
KeyInput.Size = UDim2.new(1, -12, 1, 0)
KeyInput.Position = UDim2.new(0, 6, 0, 0)
KeyInput.BackgroundTransparency = 1
KeyInput.PlaceholderText = "Paste AQ. Gemini Key..."
KeyInput.PlaceholderColor3 = Color3.fromRGB(120, 120, 120)
KeyInput.Text = ""
KeyInput.TextColor3 = Color3.fromRGB(230, 230, 230)
KeyInput.TextSize = 12
KeyInput.Font = Enum.Font.Gotham
KeyInput.ClearTextOnFocus = false
KeyInput.Active = true
KeyInput.ZIndex = 3
KeyInput.Parent = KeyFrame
-- Model Selection Button
local ModelBtn = Instance.new("TextButton")
ModelBtn.Size = UDim2.new(1, -20, 0, 30)
ModelBtn.Position = UDim2.new(0, 10, 0, 84)
ModelBtn.BackgroundColor3 = Color3.fromRGB(38, 40, 46)
ModelBtn.Text = "Model: Gemini 3.6 Flash ▼"
ModelBtn.TextColor3 = Color3.fromRGB(138, 180, 248)
ModelBtn.TextSize = 12
ModelBtn.Font = Enum.Font.GothamMedium
ModelBtn.Active = true
ModelBtn.ZIndex = 5
ModelBtn.Parent = MainFrame
local ModelCorner = Instance.new("UICorner")
ModelCorner.CornerRadius = UDim.new(0, 6)
ModelCorner.Parent = ModelBtn
-- Dropdown Menu Frame
local DropdownList = Instance.new("Frame")
DropdownList.Size = UDim2.new(1, -20, 0, 120)
DropdownList.Position = UDim2.new(0, 10, 0, 116)
DropdownList.BackgroundColor3 = Color3.fromRGB(28, 29, 33)
DropdownList.BorderSizePixel = 0
DropdownList.Visible = false
DropdownList.ZIndex = 20 -- High ZIndex guarantees it renders above chat
DropdownList.Active = true
DropdownList.Parent = MainFrame
local DropCorner = Instance.new("UICorner")
DropCorner.CornerRadius = UDim.new(0, 6)
DropCorner.Parent = DropdownList
local DropLayout = Instance.new("UIListLayout")
DropLayout.SortOrder = Enum.SortOrder.LayoutOrder
DropLayout.Parent = DropdownList
for _, item in ipairs(ModelsList) do
local ItemBtn = Instance.new("TextButton")
ItemBtn.Size = UDim2.new(1, 0, 0, 30)
ItemBtn.BackgroundTransparency = 1
ItemBtn.Text = " " .. item.Name
ItemBtn.TextColor3 = Color3.fromRGB(220, 220, 220)
ItemBtn.TextSize = 11
ItemBtn.Font = Enum.Font.Gotham
ItemBtn.TextXAlignment = Enum.TextXAlignment.Left
ItemBtn.Active = true
ItemBtn.ZIndex = 21
ItemBtn.Parent = DropdownList
ItemBtn.Activated:Connect(function()
SelectedModelID = item.ID
ModelBtn.Text = "Model: " .. item.Name .. " ▼"
DropdownList.Visible = false
end)
end
ModelBtn.Activated:Connect(function()
DropdownList.Visible = not DropdownList.Visible
end)
-- Chat Scroll View
local ChatScroll = Instance.new("ScrollingFrame")
ChatScroll.Size = UDim2.new(1, -20, 1, -170)
ChatScroll.Position = UDim2.new(0, 10, 0, 120)
ChatScroll.BackgroundTransparency = 1
ChatScroll.BorderSizePixel = 0
ChatScroll.ScrollBarThickness = 3
ChatScroll.ScrollBarImageColor3 = Color3.fromRGB(80, 80, 80)
ChatScroll.CanvasSize = UDim2.new(0, 0, 0, 0)
ChatScroll.ZIndex = 2
ChatScroll.Parent = MainFrame
local UIListLayout = Instance.new("UIListLayout")
UIListLayout.Padding = UDim.new(0, 8)
UIListLayout.SortOrder = Enum.SortOrder.LayoutOrder
UIListLayout.Parent = ChatScroll
UIListLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
ChatScroll.CanvasSize = UDim2.new(0, 0, 0, UIListLayout.AbsoluteContentSize.Y + 8)
ChatScroll.CanvasPosition = Vector2.new(0, UIListLayout.AbsoluteContentSize.Y)
end)
-- Loading Screen Overlay
local LoadingFrame = Instance.new("Frame")
LoadingFrame.Size = UDim2.new(1, 0, 1, -40)
LoadingFrame.Position = UDim2.new(0, 0, 0, 40)
LoadingFrame.BackgroundColor3 = Color3.fromRGB(15, 16, 18)
LoadingFrame.BackgroundTransparency = 0.3
LoadingFrame.BorderSizePixel = 0
LoadingFrame.Visible = false
LoadingFrame.ZIndex = 50
LoadingFrame.Active = true
LoadingFrame.Parent = MainFrame
local LoadingLabel = Instance.new("TextLabel")
LoadingLabel.Size = UDim2.new(1, 0, 0, 30)
LoadingLabel.Position = UDim2.new(0, 0, 0.45, 0)
LoadingLabel.BackgroundTransparency = 1
LoadingLabel.Text = "⏳ Thinking..."
LoadingLabel.TextColor3 = Color3.fromRGB(138, 180, 248)
LoadingLabel.TextSize = 14
LoadingLabel.Font = Enum.Font.GothamBold
LoadingLabel.ZIndex = 51
LoadingLabel.Parent = LoadingFrame
-- Bottom Input Area
local InputFrame = Instance.new("Frame")
InputFrame.Size = UDim2.new(1, -20, 0, 38)
InputFrame.Position = UDim2.new(0, 10, 1, -44)
InputFrame.BackgroundColor3 = Color3.fromRGB(32, 33, 37)
InputFrame.BorderSizePixel = 0
InputFrame.Active = true
InputFrame.ZIndex = 2
InputFrame.Parent = MainFrame
local InputCorner = Instance.new("UICorner")
InputCorner.CornerRadius = UDim.new(0, 19)
InputCorner.Parent = InputFrame
local MessageInput = Instance.new("TextBox")
MessageInput.Size = UDim2.new(1, -48, 1, 0)
MessageInput.Position = UDim2.new(0, 12, 0, 0)
MessageInput.BackgroundTransparency = 1
MessageInput.PlaceholderText = "Ask Gemini..."
MessageInput.PlaceholderColor3 = Color3.fromRGB(130, 130, 130)
MessageInput.Text = ""
MessageInput.TextColor3 = Color3.fromRGB(240, 240, 240)
MessageInput.TextSize = 12
MessageInput.Font = Enum.Font.Gotham
MessageInput.TextXAlignment = Enum.TextXAlignment.Left
MessageInput.ClearTextOnFocus = false
MessageInput.Active = true
MessageInput.ZIndex = 3
MessageInput.Parent = InputFrame
local SendBtn = Instance.new("TextButton")
SendBtn.Size = UDim2.new(0, 32, 0, 32)
SendBtn.Position = UDim2.new(1, -35, 0, 3)
SendBtn.BackgroundColor3 = Color3.fromRGB(138, 180, 248)
SendBtn.Text = "➔"
SendBtn.TextColor3 = Color3.fromRGB(20, 20, 20)
SendBtn.TextSize = 14
SendBtn.Font = Enum.Font.GothamBold
SendBtn.Active = true
SendBtn.ZIndex = 4
SendBtn.Parent = InputFrame
local SendCorner = Instance.new("UICorner")
SendCorner.CornerRadius = UDim.new(0, 16)
SendCorner.Parent = SendBtn
-- Smooth Drag System for Mobile & Desktop
local dragging = false
local dragStart, startPos
Header.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
dragStart = input.Position
startPos = MainFrame.Position
end
end)
UserInputService.InputChanged:Connect(function(input)
if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
local delta = input.Position - dragStart
MainFrame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
end
end)
UserInputService.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = false
end
end)
CloseBtn.Activated:Connect(function() ScreenGui:Destroy() end)
-- Bubble Generator
local function addMessageBubble(sender, text)
local isUser = (sender == "User")
local BubbleFrame = Instance.new("Frame")
BubbleFrame.Size = UDim2.new(1, 0, 0, 0)
BubbleFrame.BackgroundTransparency = 1
BubbleFrame.ZIndex = 3
BubbleFrame.Parent = ChatScroll
local Bubble = Instance.new("Frame")
Bubble.BackgroundColor3 = isUser and Color3.fromRGB(42, 52, 68) or Color3.fromRGB(32, 33, 37)
Bubble.BorderSizePixel = 0
Bubble.Position = isUser and UDim2.new(1, 0, 0, 0) or UDim2.new(0, 0, 0, 0)
Bubble.AnchorPoint = isUser and Vector2.new(1, 0) or Vector2.new(0, 0)
Bubble.ZIndex = 3
Bubble.Parent = BubbleFrame
local BubbleCorner = Instance.new("UICorner")
BubbleCorner.CornerRadius = UDim.new(0, 10)
BubbleCorner.Parent = Bubble
local TextLabel = Instance.new("TextLabel")
TextLabel.Size = UDim2.new(1, -16, 1, -12)
TextLabel.Position = UDim2.new(0, 8, 0, 6)
TextLabel.BackgroundTransparency = 1
TextLabel.Text = text
TextLabel.TextColor3 = isUser and Color3.fromRGB(230, 240, 255) or Color3.fromRGB(220, 220, 220)
TextLabel.TextSize = 12
TextLabel.Font = Enum.Font.Gotham
TextLabel.TextWrapped = true
TextLabel.TextXAlignment = Enum.TextXAlignment.Left
TextLabel.ZIndex = 4
TextLabel.Parent = Bubble
local textBounds = TextService:GetTextSize(text, 12, Enum.Font.Gotham, Vector2.new(200, 2000))
local finalWidth = math.clamp(textBounds.X + 20, 50, 210)
local finalHeight = textBounds.Y + 14
BubbleFrame.Size = UDim2.new(1, 0, 0, finalHeight)
Bubble.Size = UDim2.new(0, finalWidth, 0, finalHeight)
return Bubble, TextLabel
end
-- Process Request
local function processSend()
local text = MessageInput.Text
if not text:match("%S") then return end
local key = KeyInput.Text:gsub("%s+", "")
if key == "" then
addMessageBubble("Gemini", "⚠️ Please paste your API Key above.")
return
end
MessageInput.Text = ""
addMessageBubble("User", text)
table.insert(ConversationHistory, { role = "user", parts = { { text = text } } })
DropdownList.Visible = false
LoadingFrame.Visible = true
local endpoint = string.format("https://generativelanguage.googleapis.com/v1beta/models/%s:generateContent", SelectedModelID)
local payload = HttpService:JSONEncode({ contents = ConversationHistory })
task.spawn(function()
local reqSuccess, response = pcall(function()
return httpRequest({
Url = endpoint,
Method = "POST",
Headers = {
["Content-Type"] = "application/json",
["x-goog-api-key"] = key
},
Body = payload
})
end)
LoadingFrame.Visible = false
if reqSuccess and response then
local responseBody = response.Body or response.body
local decodeSuccess, decoded = pcall(function() return HttpService:JSONDecode(responseBody) end)
if decodeSuccess and decoded then
if decoded.candidates and decoded.candidates[1] then
local replyText = decoded.candidates[1].content.parts[1].text
table.insert(ConversationHistory, { role = "model", parts = { { text = replyText } } })
addMessageBubble("Gemini", replyText)
elseif decoded.error then
addMessageBubble("Gemini", "⚠️ " .. tostring(decoded.error.message or "API Error"))
else
addMessageBubble("Gemini", "⚠️ Unrecognized response format.")
end
else
addMessageBubble("Gemini", "⚠️ Failed to parse API JSON.")
end
else
addMessageBubble("Gemini", "⚠️ HTTP Request Blocked or Offline.")
end
end)
end
-- Events
SendBtn.Activated:Connect(processSend)
MessageInput.FocusLost:Connect(function(enterPressed)
if enterPressed then
processSend()
end
end)
addMessageBubble("Gemini", "Paste your key, tap Model to change AI, and ask away!")No comments yet for this script.



