Advanced AI sidebar + safer automation + improved ad filtering + performance system
// ==UserScript==
// @name Exo Client (Advanced)
// @namespace exo.client
// @version 2.0
// @description Advanced AI sidebar + safer automation + improved ad filtering + performance system
// @match *://*/*
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// @connect *
// ==/UserScript==
(function() {
'use strict';
/* ---------------- CONFIG ---------------- */
const CONFIG = {
AI_ENDPOINT: "https://openrouter.ai/api/v1/chat/completions",
API_KEY: "PUT_KEY_HERE",
MODEL: "openai/gpt-4o-mini"
};
/* ---------------- STATE ---------------- */
let isOpen = false;
let rafId = null;
/* ---------------- UI ---------------- */
const btn = document.createElement('div');
btn.id = 'exo-btn';
btn.innerHTML = '✦';
document.body.appendChild(btn);
const sidebar = document.createElement('div');
sidebar.id = 'exo-sidebar';
sidebar.innerHTML = `
<div id="exo-header">Exo Client</div>
<div id="exo-chat"></div>
<div id="exo-input-wrap">
<input id="exo-input" placeholder="Ask Exo to do anything…" />
</div>`;
document.body.appendChild(sidebar);
GM_addStyle(`
#exo-btn {
position: fixed;
bottom: 20px;
right: 20px;
width: 50px;
height: 50px;
background: rgba(255,255,255,0.1);
backdrop-filter: blur(12px);
border-radius: 50%;
display:flex;
align-items:center;
justify-content:center;
font-size:20px;
cursor:pointer;
z-index:999999;
transition: opacity 0.3s;
}
#exo-btn:hover { opacity: 1; }
#exo-sidebar {
position: fixed;
top:0;
right:-420px;
width:420px;
height:100%;
background: rgba(20,20,20,0.9);
backdrop-filter: blur(20px);
color:white;
transition: right 0.35s cubic-bezier(.4,0,.2,1);
display:flex;
flex-direction:column;
z-index:999998;
font-family: 'Product Sans', sans-serif;
}
#exo-sidebar.open { right:0; }
#exo-header { padding:16px; font-size:18px; }
#exo-chat { flex:1; overflow:auto; padding:10px; }
#exo-input-wrap { padding:10px; }
#exo-input { width:100%; padding:12px; border-radius:12px; border:none; }
`);
btn.onclick = toggleSidebar;
function toggleSidebar(){
isOpen = !isOpen;
sidebar.classList.toggle('open');
if(!isOpen) cleanup();
}
document.addEventListener('keydown', e => {
if(e.ctrlKey && e.shiftKey && e.key.toLowerCase()==='x') toggleSidebar();
});
/* ---------------- CHAT ---------------- */
const input = document.getElementById('exo-input');
const chat = document.getElementById('exo-chat');
input.addEventListener('keydown', async e => {
if(e.key === 'Enter'){
const msg = input.value.trim();
if(!msg) return;
input.value = '';
addMsg('user', msg);
const aiResponse = await callAI(msg);
addMsg('ai', aiResponse.raw);
if(aiResponse.actions) runActions(aiResponse.actions);
}
});
function addMsg(role, text){
const div = document.createElement('div');
div.textContent = text;
div.style.margin = '6px 0';
div.style.opacity = role==='ai'?0.8:1;
chat.appendChild(div);
chat.scrollTop = chat.scrollHeight;
}
/* ---------------- AI SYSTEM ---------------- */
async function callAI(prompt){
const res = await fetch(CONFIG.AI_ENDPOINT, {
method:'POST',
headers:{
'Authorization': 'Bearer ' + CONFIG.API_KEY,
'Content-Type':'application/json'
},
body: JSON.stringify({
model: CONFIG.MODEL,
messages:[{
role:'system',
content:`Return JSON only. Format: {"actions":[],"message":""}`
},{
role:'user', content: prompt}]
})
});
const data = await res.json();
let text = data.choices?.[0]?.message?.content || '{}';
try{
const parsed = JSON.parse(text);
return { raw: parsed.message || text, actions: parsed.actions || [] };
}catch{
return { raw: text };
}
}
/* ---------------- SAFE AUTOMATION ---------------- */
function runActions(actions){
actions.forEach(a => {
try{
if(a.type === 'click'){
document.querySelector(a.selector)?.click();
}
if(a.type === 'input'){
const el = document.querySelector(a.selector);
if(el) el.value = a.value;
}
if(a.type === 'scroll'){
window.scrollBy(0, a.amount || 500);
}
}catch(e){ console.warn('Action failed', a); }
});
}
/* ---------------- SMART ADBLOCK ---------------- */
const blockedPatterns = [/ads?/i, /doubleclick/, /tracker/];
const origFetch = window.fetch;
window.fetch = async (...args) => {
const url = args[0]?.toString?.() || '';
if(blockedPatterns.some(r => r.test(url))){
return new Response('', {status:200});
}
return origFetch(...args);
};
/* ---------------- VIDEO QUALITY BOOST ---------------- */
function boostVideo(){
document.querySelectorAll('video').forEach(v => {
v.playbackRate = 1;
v.setAttribute('playsinline','');
});
}
/* ---------------- PERFORMANCE LOOP ---------------- */
function loop(){
boostVideo();
rafId = requestAnimationFrame(loop);
}
loop();
function cleanup(){
cancelAnimationFrame(rafId);
}
})();