Ctrl+Shift+E ile tam ekran AI asistan — 4 dil, osirisai.live tarzı, ES5 uyumlu
// ==UserScript==
// @name OsirisAI Live Multilang
// @namespace http://tampermonkey.net/
// @version 4.0
// @description Ctrl+Shift+E ile tam ekran AI asistan — 4 dil, osirisai.live tarzı, ES5 uyumlu
// @author hakan
// @match *://*/*
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @connect api.anthropic.com
// @run-at document-end
// ==/UserScript==
(function () {
'use strict';
/* ─── DİL PAKETLERİ ──────────────────────────────────────────── */
var LANG = {
tr: {
welcomeTitle: 'OsirisAI Live',
welcomeText: 'Herhangi bir şey sor. Canlı akıllı asistan.',
chipSummarize: '📄 Sayfayı özetle',
chipJS: '⚡ JavaScript',
chipIdea: '💡 Fikir üret',
chipAI: '🤖 AI geleceği',
statusLive: 'CANLI',
statusThinking: 'DÜŞÜNÜYOR',
clearBtn: 'Temizle',
apiKeyBtn: 'API Anahtarı',
contextBtn: '📋 Sayfa',
inputPlaceholder: 'Bir şey sor... (Enter ile gönder, Shift+Enter yeni satır)',
sendTitle: 'Gönder',
hint: '<kbd>Enter</kbd> gönder · <kbd>Shift+Enter</kbd> yeni satır · <kbd>Esc</kbd> kapat',
pageInfoLabel: 'Mevcut Sayfa',
shortcutsLabel: 'Kısayollar',
shortcutOpen: 'Aç / Kapat',
shortcutSend: 'Gönder',
shortcutNewLine: 'Yeni satır',
shortcutClear: 'Temizle',
shortcutClose: 'Kapat',
modelInfo: 'Model: claude-sonnet-4<br>Akış: Canlı<br>Token: 2048<br>Geçmiş: 20 mesaj',
apiKeyTitle: '🔑 API Anahtarı',
apiKeyDesc: 'Anthropic API anahtarınızı girin. Anahtar yalnızca tarayıcınızda saklanır.',
apiKeyPlaceholder: 'sk-ant-...',
apiKeySave: 'Kaydet & Devam Et',
apiKeyNote: 'Anahtar yok mu? <a href="https://console.anthropic.com/keys" target="_blank">console.anthropic.com</a>\'dan al.',
systemPrompt: 'Sen OsirisAI\'sın. Kullanıcıya net, doğrudan ve yararlı yanıtlar ver. Türkçe konuş.',
errorGeneric: '⚠ Bağlantı hatası. API anahtarını ve internet bağlantını kontrol et.',
errorTimeout: '⏱ İstek zaman aşımına uğradı.',
errorFormat: 'Beklenmeyen yanıt formatı.',
copyBtn: 'Kopyala',
copiedBtn: '✓ Kopyalandı',
langLabel: 'Dil',
},
en: {
welcomeTitle: 'OsirisAI Live',
welcomeText: 'Ask anything. Live intelligent assistant.',
chipSummarize: '📄 Summarize page',
chipJS: '⚡ JavaScript',
chipIdea: '💡 Give me an idea',
chipAI: '🤖 Future of AI',
statusLive: 'LIVE',
statusThinking: 'THINKING',
clearBtn: 'Clear',
apiKeyBtn: 'API Key',
contextBtn: '📋 Page',
inputPlaceholder: 'Ask something... (Enter to send, Shift+Enter new line)',
sendTitle: 'Send',
hint: '<kbd>Enter</kbd> send · <kbd>Shift+Enter</kbd> new line · <kbd>Esc</kbd> close',
pageInfoLabel: 'Current Page',
shortcutsLabel: 'Shortcuts',
shortcutOpen: 'Open / Close',
shortcutSend: 'Send',
shortcutNewLine: 'New line',
shortcutClear: 'Clear',
shortcutClose: 'Close',
modelInfo: 'Model: claude-sonnet-4<br>Stream: Live<br>Token: 2048<br>History: 20 msg',
apiKeyTitle: '🔑 API Key',
apiKeyDesc: 'Enter your Anthropic API key. It is stored only in your browser.',
apiKeyPlaceholder: 'sk-ant-...',
apiKeySave: 'Save & Continue',
apiKeyNote: 'No key? Get it at <a href="https://console.anthropic.com/keys" target="_blank">console.anthropic.com</a>',
systemPrompt: 'You are OsirisAI. Give clear, direct and helpful answers. Speak English.',
errorGeneric: '⚠ Connection error. Check your API key and internet connection.',
errorTimeout: '⏱ Request timed out.',
errorFormat: 'Unexpected response format.',
copyBtn: 'Copy',
copiedBtn: '✓ Copied',
langLabel: 'Language',
},
ru: {
welcomeTitle: 'OsirisAI Live',
welcomeText: 'Спрашивайте что угодно. Живой ИИ-ассистент.',
chipSummarize: '📄 Резюме страницы',
chipJS: '⚡ JavaScript',
chipIdea: '💡 Идея',
chipAI: '🤖 Будущее ИИ',
statusLive: 'ОНЛАЙН',
statusThinking: 'ДУМАЕТ',
clearBtn: 'Очистить',
apiKeyBtn: 'API ключ',
contextBtn: '📋 Страница',
inputPlaceholder: 'Спросите... (Enter – отправить, Shift+Enter – новая строка)',
sendTitle: 'Отправить',
hint: '<kbd>Enter</kbd> отправить · <kbd>Shift+Enter</kbd> строка · <kbd>Esc</kbd> закрыть',
pageInfoLabel: 'Текущая страница',
shortcutsLabel: 'Горячие клавиши',
shortcutOpen: 'Открыть / Закрыть',
shortcutSend: 'Отправить',
shortcutNewLine: 'Новая строка',
shortcutClear: 'Очистить',
shortcutClose: 'Закрыть',
modelInfo: 'Модель: claude-sonnet-4<br>Поток: живой<br>Токенов: 2048<br>История: 20',
apiKeyTitle: '🔑 API ключ',
apiKeyDesc: 'Введите ваш ключ API Anthropic. Хранится только в браузере.',
apiKeyPlaceholder: 'sk-ant-...',
apiKeySave: 'Сохранить и продолжить',
apiKeyNote: 'Нет ключа? Получите на <a href="https://console.anthropic.com/keys" target="_blank">console.anthropic.com</a>',
systemPrompt: 'Ты OsirisAI. Давай чёткие, прямые и полезные ответы. Говори по-русски.',
errorGeneric: '⚠ Ошибка соединения. Проверьте ключ API и интернет.',
errorTimeout: '⏱ Время ожидания истекло.',
errorFormat: 'Неожиданный формат ответа.',
copyBtn: 'Копировать',
copiedBtn: '✓ Скопировано',
langLabel: 'Язык',
},
ar: {
welcomeTitle: 'OsirisAI Live',
welcomeText: 'اسأل أي شيء. مساعد ذكي مباشر.',
chipSummarize: '📄 لخّص الصفحة',
chipJS: '⚡ جافا سكريبت',
chipIdea: '💡 أعطني فكرة',
chipAI: '🤖 مستقبل الذكاء الاصطناعي',
statusLive: 'مباشر',
statusThinking: 'يفكر',
clearBtn: 'مسح',
apiKeyBtn: 'مفتاح API',
contextBtn: '📋 الصفحة',
inputPlaceholder: 'اسأل شيئًا... (Enter للإرسال، Shift+Enter سطر جديد)',
sendTitle: 'إرسال',
hint: '<kbd>Enter</kbd> إرسال · <kbd>Shift+Enter</kbd> سطر جديد · <kbd>Esc</kbd> إغلاق',
pageInfoLabel: 'الصفحة الحالية',
shortcutsLabel: 'اختصارات',
shortcutOpen: 'فتح / إغلاق',
shortcutSend: 'إرسال',
shortcutNewLine: 'سطر جديد',
shortcutClear: 'مسح',
shortcutClose: 'إغلاق',
modelInfo: 'النموذج: claude-sonnet-4<br>البث: مباشر<br>الرموز: 2048<br>السجل: 20',
apiKeyTitle: '🔑 مفتاح API',
apiKeyDesc: 'أدخل مفتاح Anthropic API. يُخزّن في متصفحك فقط.',
apiKeyPlaceholder: 'sk-ant-...',
apiKeySave: 'حفظ ومتابعة',
apiKeyNote: 'لا يوجد مفتاح؟ احصل عليه من <a href="https://console.anthropic.com/keys" target="_blank">console.anthropic.com</a>',
systemPrompt: 'أنت OsirisAI. قدّم إجابات واضحة ومباشرة ومفيدة. تحدث بالعربية.',
errorGeneric: '⚠ خطأ في الاتصال. تحقق من مفتاح API والإنترنت.',
errorTimeout: '⏱ انتهت مهلة الطلب.',
errorFormat: 'تنسيق استجابة غير متوقع.',
copyBtn: 'نسخ',
copiedBtn: '✓ تم النسخ',
langLabel: 'اللغة',
}
};
/* ─── YAPILANDIRMA ─────────────────────────────────────────────── */
var CONFIG = {
API_KEY: GM_getValue('osiris_api_key_v4', ''),
MODEL: 'claude-sonnet-4-20250514',
MAX_TOKENS: 2048,
MAX_HISTORY: 20,
currentLang: GM_getValue('osiris_lang', 'tr'), // varsayılan Türkçe
};
// Dil değişince sistem prompt’u anlık al
function getSystemPrompt() {
return LANG[CONFIG.currentLang].systemPrompt;
}
/* ─── STİL (osirisai.live havası) ───────────────────────────────── */
GM_addStyle([
'@import url(\'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap\');',
'#osiris-overlay {',
' position: fixed; inset: 0; z-index: 2147483647;',
' background: #0a0a12;',
' font-family: \'Inter\', system-ui, sans-serif;',
' display: flex; flex-direction: column;',
' opacity: 0; transform: scale(0.97);',
' transition: opacity 0.2s ease, transform 0.2s ease;',
' pointer-events: none;',
'}',
'#osiris-overlay.osiris-visible {',
' opacity: 1; transform: scale(1); pointer-events: all;',
'}',
'#osiris-overlay::before {',
' content: \'\'; position: absolute; inset: 0;',
' background-image:',
' linear-gradient(rgba(255,255,255,0.02) 1px, transparent 1px),',
' linear-gradient(90deg, rgba(255,255,255,0.02) 1px, transparent 1px);',
' background-size: 60px 60px; pointer-events: none;',
'}',
'#osiris-header {',
' display: flex; align-items: center; justify-content: space-between;',
' padding: 14px 24px;',
' border-bottom: 1px solid rgba(255,255,255,0.06);',
' background: rgba(10,10,18,0.94); backdrop-filter: blur(12px);',
' flex-shrink: 0; position: relative; z-index: 2;',
'}',
'#osiris-logo { display: flex; align-items: center; gap: 8px; }',
'#osiris-logo svg { width: 24px; height: 24px; filter: drop-shadow(0 0 6px rgba(255,90,0,0.5)); }',
'#osiris-logo-text {',
' font-size: 18px; font-weight: 800; letter-spacing: -0.5px;',
' background: linear-gradient(135deg, #ff5a00, #ffb74d);',
' -webkit-background-clip: text; -webkit-text-fill-color: transparent;',
'}',
'#osiris-status { display: flex; align-items: center; gap: 6px; font-size: 10px; color: rgba(255,255,255,0.3); }',
'#osiris-status-dot {',
' width: 5px; height: 5px; border-radius: 50%;',
' background: #22c55e; box-shadow: 0 0 6px #22c55e;',
' animation: osiris-pulse 2s infinite;',
'}',
'#osiris-status-dot.thinking {',
' background: #ff9a3c; box-shadow: 0 0 6px #ff9a3c;',
' animation: osiris-blink 0.6s infinite;',
'}',
'@keyframes osiris-pulse { 0%,100% { opacity:1; } 50% { opacity:0.4; } }',
'@keyframes osiris-blink { 0%,100% { opacity:1; } 50% { opacity:0.2; } }',
'#osiris-header-right { display: flex; align-items: center; gap: 8px; }',
'.osiris-header-btn {',
' background: none; border: 1px solid rgba(255,255,255,0.06);',
' color: rgba(255,255,255,0.35); padding: 4px 10px; border-radius: 5px;',
' font-family: \'Inter\', sans-serif; font-size: 10px; cursor: pointer; transition: all 0.2s;',
'}',
'.osiris-header-btn:hover { border-color: rgba(255,90,0,0.3); color: #ff9a3c; }',
'#osiris-lang-select {',
' background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08);',
' color: rgba(255,255,255,0.6); border-radius: 5px; padding: 4px 6px;',
' font-size: 10px; cursor: pointer; outline: none; font-family: \'Inter\', sans-serif;',
'}',
'#osiris-lang-select option { background: #0a0a12; color: white; }',
'#osiris-close {',
' background: none; border: none; color: rgba(255,255,255,0.2);',
' cursor: pointer; padding: 2px; border-radius: 4px; line-height: 0; transition: color 0.2s;',
'}',
'#osiris-close:hover { color: #ff5a00; }',
'#osiris-main { flex: 1; display: flex; overflow: hidden; }',
'#osiris-messages {',
' flex: 1; overflow-y: auto; padding: 24px;',
' display: flex; flex-direction: column; gap: 18px; scroll-behavior: smooth;',
'}',
'#osiris-messages::-webkit-scrollbar { width: 4px; }',
'#osiris-messages::-webkit-scrollbar-track { background: transparent; }',
'#osiris-messages::-webkit-scrollbar-thumb { background: rgba(255,90,0,0.12); border-radius: 2px; }',
'#osiris-welcome {',
' flex: 1; display: flex; flex-direction: column;',
' align-items: center; justify-content: center; gap: 12px; color: rgba(255,255,255,0.12);',
'}',
'#osiris-welcome svg { width: 48px; height: 48px; opacity: 0.1; }',
'#osiris-welcome h2 { font-size: 24px; font-weight: 800; color: rgba(255,255,255,0.05); }',
'#osiris-welcome p { font-size: 12px; color: rgba(255,255,255,0.1); }',
'#osiris-welcome-chips { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; margin-top: 12px; }',
'.osiris-chip {',
' background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.06);',
' color: rgba(255,255,255,0.3); padding: 6px 12px; border-radius: 100px;',
' font-size: 11px; cursor: pointer; transition: all 0.2s;',
'}',
'.osiris-chip:hover { background: rgba(255,90,0,0.08); border-color: rgba(255,90,0,0.2); color: #ff9a3c; }',
'.osiris-msg { display: flex; gap: 10px; animation: osiris-fadeup 0.25s ease; max-width: 780px; }',
'@keyframes osiris-fadeup { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:translateY(0); } }',
'.osiris-msg.user { align-self: flex-end; flex-direction: row-reverse; }',
'.osiris-msg.assistant { align-self: flex-start; }',
'.osiris-avatar {',
' width: 28px; height: 28px; border-radius: 6px; flex-shrink: 0;',
' display: flex; align-items: center; justify-content: center;',
' font-size: 12px; font-weight: 700;',
'}',
'.osiris-msg.user .osiris-avatar {',
' background: rgba(255,90,0,0.1); border: 1px solid rgba(255,90,0,0.2); color: #ff9a3c;',
'}',
'.osiris-msg.assistant .osiris-avatar {',
' background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.04);',
'}',
'.osiris-bubble {',
' max-width: 640px; padding: 12px 16px; border-radius: 10px;',
' font-size: 13px; line-height: 1.65; word-break: break-word;',
'}',
'.osiris-msg.user .osiris-bubble {',
' background: rgba(255,90,0,0.06); border: 1px solid rgba(255,90,0,0.12);',
' color: rgba(255,255,255,0.85); border-bottom-right-radius: 2px;',
'}',
'.osiris-msg.assistant .osiris-bubble {',
' background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.04);',
' color: rgba(255,255,255,0.78); border-bottom-left-radius: 2px;',
'}',
'.osiris-bubble strong { color: #ff9a3c; font-weight: 600; }',
'.osiris-bubble em { color: rgba(255,255,255,0.65); }',
'.osiris-bubble a { color: #ff9a3c; text-decoration: underline; }',
'.osiris-bubble code {',
' font-family: \'JetBrains Mono\', monospace; font-size: 11px;',
' background: rgba(255,90,0,0.06); border: 1px solid rgba(255,90,0,0.1);',
' padding: 1px 4px; border-radius: 2px; color: #ffb74d;',
'}',
'.osiris-bubble pre {',
' background: rgba(0,0,0,0.3); border: 1px solid rgba(255,255,255,0.05);',
' border-radius: 6px; padding: 12px; overflow-x: auto; margin: 6px 0; position: relative;',
'}',
'.osiris-bubble pre code { background: none; border: none; padding: 0; color: #c8bcac; }',
'.osiris-copy-btn {',
' position: absolute; top: 4px; right: 4px;',
' background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1);',
' color: rgba(255,255,255,0.35); padding: 1px 6px; border-radius: 3px;',
' font-size: 9px; cursor: pointer; transition: all 0.2s; z-index: 1;',
'}',
'.osiris-copy-btn:hover { color: #ff9a3c; border-color: rgba(255,90,0,0.3); }',
'.osiris-copy-btn.copied { color: #22c55e; border-color: #22c55e; }',
'.osiris-bubble ul, .osiris-bubble ol { padding-left: 16px; margin: 4px 0; }',
'.osiris-bubble li { margin: 2px 0; }',
'.osiris-bubble blockquote {',
' border-left: 2px solid rgba(255,90,0,0.2); padding-left: 10px;',
' margin: 6px 0; color: rgba(255,255,255,0.5); font-style: italic;',
'}',
'.osiris-typing { display: flex; gap: 3px; align-items: center; padding: 12px 16px; }',
'.osiris-typing span {',
' width: 4px; height: 4px; background: rgba(255,90,0,0.4);',
' border-radius: 50%; animation: osiris-typing 1.2s infinite;',
'}',
'.osiris-typing span:nth-child(2) { animation-delay: 0.2s; }',
'.osiris-typing span:nth-child(3) { animation-delay: 0.4s; }',
'@keyframes osiris-typing { 0%,80%,100% { transform:scale(1); opacity:0.4; } 40% { transform:scale(1.4); opacity:1; } }',
'#osiris-sidebar {',
' width: 200px; border-left: 1px solid rgba(255,255,255,0.03);',
' padding: 20px 16px; display: flex; flex-direction: column; gap: 16px; flex-shrink: 0;',
'}',
'.osiris-sidebar-section h4 {',
' font-size: 8px; font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase;',
' color: rgba(255,255,255,0.15); margin-bottom: 6px;',
'}',
'#osiris-page-info { font-size: 10px; color: rgba(255,255,255,0.2); line-height: 1.3; word-break: break-all; }',
'#osiris-shortcuts { display: flex; flex-direction: column; gap: 4px; }',
'.osiris-shortcut { display: flex; justify-content: space-between; font-size: 9px; color: rgba(255,255,255,0.18); }',
'.osiris-key {',
' background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.05);',
' border-radius: 2px; padding: 0 4px; font-family: \'JetBrains Mono\', monospace; font-size: 8px;',
'}',
'#osiris-model-info { margin-top: auto; padding-top: 12px; border-top: 1px solid rgba(255,255,255,0.03); font-size: 9px; color: rgba(255,255,255,0.1); }',
'#osiris-input-area {',
' padding: 16px 24px 20px; border-top: 1px solid rgba(255,255,255,0.04);',
' background: rgba(10,10,18,0.94); backdrop-filter: blur(14px); flex-shrink: 0; z-index: 2;',
'}',
'#osiris-input-wrap {',
' display: flex; align-items: flex-end; gap: 8px;',
' background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.06);',
' border-radius: 10px; padding: 8px 12px; transition: border-color 0.2s;',
'}',
'#osiris-input-wrap:focus-within { border-color: rgba(255,90,0,0.25); }',
'#osiris-input {',
' flex: 1; background: none; border: none; outline: none;',
' color: rgba(255,255,255,0.85); font-family: \'Inter\', sans-serif;',
' font-size: 13px; line-height: 1.5; resize: none;',
' min-height: 20px; max-height: 120px; overflow-y: auto;',
'}',
'#osiris-input::placeholder { color: rgba(255,255,255,0.15); }',
'#osiris-send {',
' background: linear-gradient(135deg, #ff5a00, #ff8c00);',
' border: none; border-radius: 6px; width: 32px; height: 32px;',
' cursor: pointer; display: flex; align-items: center; justify-content: center;',
' flex-shrink: 0; transition: all 0.2s;',
'}',
'#osiris-send:hover { transform: scale(1.05); box-shadow: 0 2px 12px rgba(255,90,0,0.4); }',
'#osiris-send:disabled { opacity: 0.3; cursor: not-allowed; transform: none; }',
'#osiris-send svg { width: 14px; height: 14px; color: white; }',
'#osiris-input-hint { font-size: 9px; color: rgba(255,255,255,0.1); margin-top: 6px; text-align: center; }',
'#osiris-input-hint kbd {',
' font-family: \'JetBrains Mono\', monospace; font-size: 8px;',
' background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.05);',
' border-radius: 2px; padding: 0 3px;',
'}',
'#osiris-apikey-modal {',
' position: fixed; inset: 0; z-index: 2147483648;',
' background: rgba(0,0,0,0.75); backdrop-filter: blur(6px);',
' display: flex; align-items: center; justify-content: center;',
'}',
'#osiris-apikey-box {',
' background: #0c0c18; border: 1px solid rgba(255,90,0,0.15);',
' border-radius: 14px; padding: 30px; width: 400px; box-shadow: 0 15px 40px rgba(0,0,0,0.7);',
'}',
'#osiris-apikey-box h3 { font-size: 18px; font-weight: 800; color: white; margin-bottom: 4px; }',
'#osiris-apikey-box p { font-size: 11px; color: rgba(255,255,255,0.25); margin-bottom: 16px; line-height: 1.4; }',
'#osiris-apikey-input {',
' width: 100%; background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.06);',
' border-radius: 6px; padding: 8px 12px; font-family: \'JetBrains Mono\', monospace;',
' font-size: 11px; color: rgba(255,255,255,0.7); outline: none;',
' margin-bottom: 12px; box-sizing: border-box;',
'}',
'#osiris-apikey-input:focus { border-color: rgba(255,90,0,0.3); }',
'#osiris-apikey-save {',
' width: 100%; background: linear-gradient(135deg, #ff5a00, #ff8c00);',
' border: none; border-radius: 6px; padding: 9px;',
' font-family: \'Inter\', sans-serif; font-size: 13px; font-weight: 700;',
' color: white; cursor: pointer; transition: all 0.2s;',
'}',
'#osiris-apikey-save:hover { box-shadow: 0 2px 12px rgba(255,90,0,0.35); }',
'#osiris-apikey-note { margin-top: 10px; font-size: 9px; color: rgba(255,255,255,0.15); text-align: center; }',
'#osiris-context-btn {',
' background: rgba(255,255,255,0.02); border: 1px solid rgba(255,255,255,0.05);',
' color: rgba(255,255,255,0.25); padding: 3px 8px; border-radius: 4px;',
' font-size: 9px; cursor: pointer; font-family: \'Inter\', sans-serif; white-space: nowrap;',
'}',
'#osiris-context-btn:hover, #osiris-context-btn.active { border-color: rgba(255,90,0,0.2); color: #ff9a3c; }',
'#osiris-context-btn.active { background: rgba(255,90,0,0.05); }',
].join('\n'));
/* ─── DURUM ──────────────────────────────────────────────────────── */
var isOpen = false;
var isThinking = false;
var messages = [];
var includeContext = false;
var streamBuffer = '';
var currentAssistantEl = null;
var lastProcessedByte = 0;
/* ─── OVERLAY OLUŞTUR ────────────────────────────────────────────── */
function buildOverlay() {
var t = LANG[CONFIG.currentLang];
var overlay = document.createElement('div');
overlay.id = 'osiris-overlay';
overlay.innerHTML = [
'<div id="osiris-header">',
' <div id="osiris-logo">',
' <svg viewBox="0 0 32 32"><polygon points="16,3 26,26 6,26" fill="none" stroke="#ff5a00" stroke-width="2"/><circle cx="16" cy="17" r="3" fill="#ff5a00"/></svg>',
' <span id="osiris-logo-text">OSIRIS AI</span>',
' </div>',
' <div id="osiris-status">',
' <div id="osiris-status-dot"></div>',
' <span id="osiris-status-text">' + t.statusLive + '</span>',
' </div>',
' <div id="osiris-header-right">',
' <select id="osiris-lang-select">',
' <option value="tr">🇹🇷 TR</option>',
' <option value="en">🇬🇧 EN</option>',
' <option value="ru">🇷🇺 RU</option>',
' <option value="ar">🇸🇦 AR</option>',
' </select>',
' <button class="osiris-header-btn" id="osiris-clear-btn">' + t.clearBtn + '</button>',
' <button class="osiris-header-btn" id="osiris-apikey-btn">' + t.apiKeyBtn + '</button>',
' <button id="osiris-close"><svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2"><path d="M16 4L4 16M4 4l12 12"/></svg></button>',
' </div>',
'</div>',
'<div id="osiris-main">',
' <div id="osiris-messages">',
' <div id="osiris-welcome">',
' <svg viewBox="0 0 48 48"><polygon points="24,4 42,42 6,42" fill="none" stroke="currentColor" stroke-width="2"/><circle cx="24" cy="26" r="4" fill="currentColor"/></svg>',
' <h2>' + t.welcomeTitle + '</h2>',
' <p>' + t.welcomeText + '</p>',
' <div id="osiris-welcome-chips">',
' <div class="osiris-chip" data-prompt="' + (CONFIG.currentLang === 'tr' ? 'Bu sayfayı özetle' : CONFIG.currentLang === 'en' ? 'Summarize this page' : CONFIG.currentLang === 'ru' ? 'Сделай резюме страницы' : 'لخص هذه الصفحة') + '">' + t.chipSummarize + '</div>',
' <div class="osiris-chip" data-prompt="' + (CONFIG.currentLang === 'tr' ? 'JavaScript hakkında kısa bilgi ver' : CONFIG.currentLang === 'en' ? 'Tell me about JavaScript' : CONFIG.currentLang === 'ru' ? 'Расскажи о JavaScript' : 'أخبرني عن جافا سكريبت') + '">' + t.chipJS + '</div>',
' <div class="osiris-chip" data-prompt="' + (CONFIG.currentLang === 'tr' ? 'Bana yaratıcı bir fikir ver' : CONFIG.currentLang === 'en' ? 'Give me a creative idea' : CONFIG.currentLang === 'ru' ? 'Дай творческую идею' : 'أعطني فكرة إبداعية') + '">' + t.chipIdea + '</div>',
' <div class="osiris-chip" data-prompt="' + (CONFIG.currentLang === 'tr' ? 'Yapay zekanın geleceği nedir?' : CONFIG.currentLang === 'en' ? 'What is the future of AI?' : CONFIG.currentLang === 'ru' ? 'Какое будущее у ИИ?' : 'ما هو مستقبل الذكاء الاصطناعي؟') + '">' + t.chipAI + '</div>',
' </div>',
' </div>',
' </div>',
' <div id="osiris-sidebar">',
' <div class="osiris-sidebar-section"><h4>' + t.pageInfoLabel + '</h4><div id="osiris-page-info"></div></div>',
' <div class="osiris-sidebar-section"><h4>' + t.shortcutsLabel + '</h4><div id="osiris-shortcuts">',
' <div class="osiris-shortcut"><span>' + t.shortcutOpen + '</span><span class="osiris-key">Ctrl+Shift+E</span></div>',
' <div class="osiris-shortcut"><span>' + t.shortcutSend + '</span><span class="osiris-key">Enter</span></div>',
' <div class="osiris-shortcut"><span>' + t.shortcutNewLine + '</span><span class="osiris-key">Shift+Enter</span></div>',
' <div class="osiris-shortcut"><span>' + t.shortcutClear + '</span><span class="osiris-key">Ctrl+L</span></div>',
' <div class="osiris-shortcut"><span>' + t.shortcutClose + '</span><span class="osiris-key">Esc</span></div>',
' </div></div>',
' <div id="osiris-model-info">' + t.modelInfo + '</div>',
' </div>',
'</div>',
'<div id="osiris-input-area">',
' <div id="osiris-input-wrap">',
' <button id="osiris-context-btn" title="Sayfa içeriğini dahil et">' + t.contextBtn + '</button>',
' <textarea id="osiris-input" rows="1" placeholder="' + t.inputPlaceholder + '"></textarea>',
' <button id="osiris-send" title="' + t.sendTitle + '"><svg fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path d="M22 2L11 13M22 2L15 22l-4-9-9-4 20-7z"/></svg></button>',
' </div>',
' <div id="osiris-input-hint">' + t.hint + '</div>',
'</div>',
].join('\n');
document.body.appendChild(overlay);
document.getElementById('osiris-lang-select').value = CONFIG.currentLang;
updatePageInfo();
bindEvents(overlay);
}
function updatePageInfo() {
var info = document.getElementById('osiris-page-info');
if (info) {
var title = document.title;
info.textContent = (title.length > 35 ? title.slice(0, 35) + '…' : title) + '\n' + window.location.hostname;
}
}
/* ─── API KEY MODAL ──────────────────────────────────────────────── */
function showApiKeyModal() {
var t = LANG[CONFIG.currentLang];
var existing = document.getElementById('osiris-apikey-modal');
if (existing) existing.remove();
var modal = document.createElement('div');
modal.id = 'osiris-apikey-modal';
modal.innerHTML = [
'<div id="osiris-apikey-box">',
' <h3>' + t.apiKeyTitle + '</h3>',
' <p>' + t.apiKeyDesc + '</p>',
' <input type="password" id="osiris-apikey-input" placeholder="' + t.apiKeyPlaceholder + '" value="' + CONFIG.API_KEY + '"/>',
' <button id="osiris-apikey-save">' + t.apiKeySave + '</button>',
' <div id="osiris-apikey-note">' + t.apiKeyNote + '</div>',
'</div>',
].join('\n');
document.body.appendChild(modal);
modal.querySelector('#osiris-apikey-input').focus();
modal.querySelector('#osiris-apikey-save').onclick = function () {
var val = modal.querySelector('#osiris-apikey-input').value.trim();
if (val) {
CONFIG.API_KEY = val;
GM_setValue('osiris_api_key_v4', val);
modal.remove();
}
};
modal.addEventListener('click', function (e) { if (e.target === modal) modal.remove(); });
}
/* ─── MARKDOWN PARSER (güçlendirilmiş) ──────────────────────────── */
function parseMarkdown(text) {
var escaped = text.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
var codeBlocks = [];
escaped = escaped.replace(/```(\w*)\n?([\s\S]*?)```/g, function (match, lang, code) {
var idx = codeBlocks.length;
codeBlocks.push(code.trim());
return '%%CODEBLOCK_' + idx + '%%';
});
escaped = escaped.replace(/`([^`]+)`/g, '<code>$1</code>');
escaped = escaped.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>');
escaped = escaped.replace(/\*\*\*(.+?)\*\*\*/g, '<strong><em>$1</em></strong>');
escaped = escaped.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
escaped = escaped.replace(/\*(.+?)\*/g, '<em>$1</em>');
escaped = escaped.replace(/^### (.+)$/gm, '<h3>$1</h3>');
escaped = escaped.replace(/^## (.+)$/gm, '<h2>$1</h2>');
escaped = escaped.replace(/^# (.+)$/gm, '<h1>$1</h1>');
escaped = escaped.replace(/^> (.+)$/gm, '<blockquote>$1</blockquote>');
var lines = escaped.split('\n'), inList = false, listType = '', out = [];
for (var i = 0; i < lines.length; i++) {
var line = lines[i], ul = line.match(/^- (.+)$/), ol = line.match(/^\d+\. (.+)$/);
if (ul) {
if (!inList || listType !== 'ul') { if (inList) out.push('</' + listType + '>'); out.push('<ul>'); inList = true; listType = 'ul'; }
out.push('<li>' + ul[1] + '</li>');
} else if (ol) {
if (!inList || listType !== 'ol') { if (inList) out.push('</' + listType + '>'); out.push('<ol>'); inList = true; listType = 'ol'; }
out.push('<li>' + ol[1] + '</li>');
} else {
if (inList) { out.push('</' + listType + '>'); inList = false; listType = ''; }
out.push(line);
}
}
if (inList) out.push('</' + listType + '>');
escaped = out.join('\n');
escaped = escaped.replace(/%%CODEBLOCK_(\d+)%%/g, function (match, idx) {
return '<pre><button class="osiris-copy-btn">' + LANG[CONFIG.currentLang].copyBtn + '</button><code>' + codeBlocks[parseInt(idx)] + '</code></pre>';
});
escaped = escaped.replace(/\n/g, '<br>');
return escaped;
}
/* ─── MESAJ EKLE ─────────────────────────────────────────────────── */
function addMessage(role, content, streaming) {
var welcome = document.getElementById('osiris-welcome');
if (welcome) welcome.remove();
var container = document.getElementById('osiris-messages');
var div = document.createElement('div');
div.className = 'osiris-msg ' + role;
var avatar = document.createElement('div');
avatar.className = 'osiris-avatar';
avatar.innerHTML = role === 'user' ? '<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg>'
: '<svg width="14" height="14" viewBox="0 0 32 32"><polygon points="16,3 26,26 6,26" fill="none" stroke="#ff5a00" stroke-width="2"/><circle cx="16" cy="17" r="3" fill="#ff5a00"/></svg>';
var bubble = document.createElement('div');
bubble.className = 'osiris-bubble';
if (streaming) {
bubble.innerHTML = '<span class="osiris-typing"><span></span><span></span><span></span></span>';
currentAssistantEl = bubble;
} else {
bubble.innerHTML = role === 'user' ? content.replace(/</g,'<').replace(/>/g,'>').replace(/\n/g,'<br>') : parseMarkdown(content);
}
div.appendChild(avatar);
div.appendChild(bubble);
container.appendChild(div);
container.scrollTop = container.scrollHeight;
return bubble;
}
/* ─── SAYFA METNİ ────────────────────────────────────────────────── */
function getPageContext() {
var bodyText = document.body.innerText;
if (bodyText.length > 4000) bodyText = bodyText.slice(0, 4000) + '...';
return '\n\n---\n[Mevcut Sayfa]\nURL: ' + window.location.href + '\nBaşlık: ' + document.title + '\n' + bodyText + '\n---\n';
}
function trimHistory() { while (messages.length > CONFIG.MAX_HISTORY) messages.shift(); }
/* ─── API ÇAĞRISI (stream) ───────────────────────────────────────── */
function sendToAI(userText) {
if (!CONFIG.API_KEY) { showApiKeyModal(); return; }
if (isThinking) return;
isThinking = true;
setStatus('thinking');
document.getElementById('osiris-send').disabled = true;
var msgContent = includeContext ? userText + getPageContext() : userText;
messages.push({ role: 'user', content: msgContent });
trimHistory();
addMessage('user', userText);
var assistantBubble = addMessage('assistant', '', true);
var body = JSON.stringify({
model: CONFIG.MODEL,
max_tokens: CONFIG.MAX_TOKENS,
system: getSystemPrompt(),
messages: messages,
stream: true,
});
streamBuffer = '';
lastProcessedByte = 0;
GM_xmlhttpRequest({
method: 'POST',
url: 'https://api.anthropic.com/v1/messages',
headers: {
'Content-Type': 'application/json',
'x-api-key': CONFIG.API_KEY,
'anthropic-version': '2023-06-01',
},
data: body,
responseType: 'text',
timeout: 120000,
onprogress: function (res) {
var full = res.responseText;
if (full.length <= lastProcessedByte) return;
var chunk = full.slice(lastProcessedByte);
lastProcessedByte = full.length;
var lines = chunk.split('\n');
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line.indexOf('data: ') !== 0) continue;
var json = line.slice(6).trim();
if (json === '[DONE]') continue;
try {
var evt = JSON.parse(json);
if (evt.type === 'content_block_delta' && evt.delta && evt.delta.text) {
streamBuffer += evt.delta.text;
assistantBubble.innerHTML = parseMarkdown(streamBuffer);
var container = document.getElementById('osiris-messages');
container.scrollTop = container.scrollHeight;
}
} catch (e) {}
}
},
onload: function (res) {
if (!streamBuffer) {
try {
var data = JSON.parse(res.responseText);
if (data.content && data.content[0] && data.content[0].text) {
streamBuffer = data.content[0].text;
} else if (data.error) {
assistantBubble.innerHTML = '<span style="color:#f87171">' + data.error.message + '</span>';
}
} catch (e) { assistantBubble.innerHTML = '<span style="color:#f87171">' + LANG[CONFIG.currentLang].errorFormat + '</span>'; }
}
if (streamBuffer) messages.push({ role: 'assistant', content: streamBuffer });
trimHistory();
finishStream();
},
onerror: function () {
assistantBubble.innerHTML = '<span style="color:#f87171">' + LANG[CONFIG.currentLang].errorGeneric + '</span>';
finishStream();
},
ontimeout: function () {
if (streamBuffer) {
assistantBubble.innerHTML = parseMarkdown(streamBuffer + '\n\n*[Zaman aşımı]*');
messages.push({ role: 'assistant', content: streamBuffer });
} else {
assistantBubble.innerHTML = '<span style="color:#f87171">' + LANG[CONFIG.currentLang].errorTimeout + '</span>';
}
finishStream();
}
});
}
function finishStream() {
isThinking = false;
currentAssistantEl = null;
setStatus('live');
document.getElementById('osiris-send').disabled = false;
document.getElementById('osiris-input').focus();
}
function setStatus(state) {
var dot = document.getElementById('osiris-status-dot');
var txt = document.getElementById('osiris-status-text');
if (!dot || !txt) return;
var t = LANG[CONFIG.currentLang];
if (state === 'thinking') {
dot.className = 'thinking';
txt.textContent = t.statusThinking;
} else {
dot.className = '';
txt.textContent = t.statusLive;
}
}
/* ─── TÜM ARAYÜZÜ DİLE GÖRE YENİLE ──────────────────────────────── */
function refreshUILanguage() {
var t = LANG[CONFIG.currentLang];
document.getElementById('osiris-status-text').textContent = t.statusLive;
document.getElementById('osiris-clear-btn').textContent = t.clearBtn;
document.getElementById('osiris-apikey-btn').textContent = t.apiKeyBtn;
var ctxBtn = document.getElementById('osiris-context-btn');
if (ctxBtn) ctxBtn.textContent = t.contextBtn;
var input = document.getElementById('osiris-input');
if (input) input.placeholder = t.inputPlaceholder;
var hint = document.getElementById('osiris-input-hint');
if (hint) hint.innerHTML = t.hint;
var sendBtn = document.getElementById('osiris-send');
if (sendBtn) sendBtn.title = t.sendTitle;
var welcome = document.getElementById('osiris-welcome');
if (welcome) {
welcome.querySelector('h2').textContent = t.welcomeTitle;
welcome.querySelector('p').textContent = t.welcomeText;
var chips = welcome.querySelectorAll('.osiris-chip');
if (chips.length) {
chips[0].textContent = t.chipSummarize;
chips[1].textContent = t.chipJS;
chips[2].textContent = t.chipIdea;
chips[3].textContent = t.chipAI;
}
}
var shortcuts = document.querySelectorAll('#osiris-shortcuts .osiris-shortcut span:first-child');
if (shortcuts.length) {
shortcuts[0].textContent = t.shortcutOpen;
shortcuts[1].textContent = t.shortcutSend;
shortcuts[2].textContent = t.shortcutNewLine;
shortcuts[3].textContent = t.shortcutClear;
shortcuts[4].textContent = t.shortcutClose;
}
var sidebarLabels = document.querySelectorAll('#osiris-sidebar .osiris-sidebar-section h4');
if (sidebarLabels.length) {
sidebarLabels[0].textContent = t.pageInfoLabel;
sidebarLabels[1].textContent = t.shortcutsLabel;
}
document.getElementById('osiris-model-info').innerHTML = t.modelInfo;
updatePageInfo();
}
/* ─── EVENT BINDING ──────────────────────────────────────────────── */
function bindEvents(overlay) {
document.getElementById('osiris-close').onclick = function () { toggle(false); };
document.getElementById('osiris-clear-btn').onclick = function () {
messages = [];
var container = document.getElementById('osiris-messages');
var t = LANG[CONFIG.currentLang];
container.innerHTML = [
'<div id="osiris-welcome">',
' <svg viewBox="0 0 48 48"><polygon points="24,4 42,42 6,42" fill="none" stroke="currentColor" stroke-width="2"/><circle cx="24" cy="26" r="4" fill="currentColor"/></svg>',
' <h2>' + t.welcomeTitle + '</h2>',
' <p>' + t.welcomeText + '</p>',
' <div id="osiris-welcome-chips">',
' <div class="osiris-chip" data-prompt="' + (CONFIG.currentLang === 'tr' ? 'Bu sayfayı özetle' : CONFIG.currentLang === 'en' ? 'Summarize this page' : CONFIG.currentLang === 'ru' ? 'Сделай резюме страницы' : 'لخص هذه الصفحة') + '">' + t.chipSummarize + '</div>',
' <div class="osiris-chip" data-prompt="' + (CONFIG.currentLang === 'tr' ? 'JavaScript hakkında kısa bilgi ver' : CONFIG.currentLang === 'en' ? 'Tell me about JavaScript' : CONFIG.currentLang === 'ru' ? 'Расскажи о JavaScript' : 'أخبرني عن جافا سكريبت') + '">' + t.chipJS + '</div>',
' <div class="osiris-chip" data-prompt="' + (CONFIG.currentLang === 'tr' ? 'Bana yaratıcı bir fikir ver' : CONFIG.currentLang === 'en' ? 'Give me a creative idea' : CONFIG.currentLang === 'ru' ? 'Дай творческую идею' : 'أعطني فكرة إبداعية') + '">' + t.chipIdea + '</div>',
' <div class="osiris-chip" data-prompt="' + (CONFIG.currentLang === 'tr' ? 'Yapay zekanın geleceği nedir?' : CONFIG.currentLang === 'en' ? 'What is the future of AI?' : CONFIG.currentLang === 'ru' ? 'Какое будущее у ИИ?' : 'ما هو مستقبل الذكاء الاصطناعي؟') + '">' + t.chipAI + '</div>',
' </div>',
'</div>',
].join('\n');
bindChips();
};
document.getElementById('osiris-apikey-btn').onclick = showApiKeyModal;
var langSelect = document.getElementById('osiris-lang-select');
langSelect.onchange = function () {
CONFIG.currentLang = this.value;
GM_setValue('osiris_lang', CONFIG.currentLang);
refreshUILanguage();
// Chip prompt'ları da güncelle
bindChips();
};
var ctxBtn = document.getElementById('osiris-context-btn');
ctxBtn.onclick = function () {
includeContext = !includeContext;
ctxBtn.className = includeContext ? 'active' : '';
};
var input = document.getElementById('osiris-input');
input.addEventListener('input', function () {
this.style.height = 'auto';
this.style.height = Math.min(this.scrollHeight, 120) + 'px';
});
input.addEventListener('keydown', function (e) {
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); doSend(); }
});
document.getElementById('osiris-send').onclick = doSend;
// Copy delegation
document.getElementById('osiris-messages').addEventListener('click', function (e) {
if (e.target.classList.contains('osiris-copy-btn')) {
var code = e.target.nextElementSibling;
if (code) {
var text = code.textContent;
navigator.clipboard.writeText(text).then(function () {
e.target.textContent = LANG[CONFIG.currentLang].copiedBtn;
e.target.classList.add('copied');
setTimeout(function () { e.target.textContent = LANG[CONFIG.currentLang].copyBtn; e.target.classList.remove('copied'); }, 2000);
}).catch(function () {
var ta = document.createElement('textarea');
ta.value = text; ta.style.position='fixed'; ta.style.opacity='0';
document.body.appendChild(ta); ta.select();
document.execCommand('copy'); document.body.removeChild(ta);
e.target.textContent = LANG[CONFIG.currentLang].copiedBtn;
e.target.classList.add('copied');
setTimeout(function () { e.target.textContent = LANG[CONFIG.currentLang].copyBtn; e.target.classList.remove('copied'); }, 2000);
});
}
}
});
updatePageInfo();
bindChips();
}
function doSend() {
var input = document.getElementById('osiris-input');
var text = input.value.trim();
if (!text || isThinking) return;
input.value = '';
input.style.height = 'auto';
sendToAI(text);
}
function bindChips() {
setTimeout(function () {
var chips = document.querySelectorAll('#osiris-welcome-chips .osiris-chip');
for (var i = 0; i < chips.length; i++) {
chips[i].onclick = function () {
var prompt = this.dataset.prompt;
document.getElementById('osiris-input').value = prompt;
doSend();
};
}
}, 100);
}
function toggle(force) {
var overlay = document.getElementById('osiris-overlay');
if (!overlay) return;
isOpen = force !== undefined ? force : !isOpen;
if (isOpen) {
overlay.classList.add('osiris-visible');
setTimeout(function () { document.getElementById('osiris-input').focus(); }, 300);
if (!CONFIG.API_KEY) setTimeout(showApiKeyModal, 400);
} else {
overlay.classList.remove('osiris-visible');
}
}
document.addEventListener('keydown', function (e) {
if (e.ctrlKey && e.shiftKey && e.key === 'E') { e.preventDefault(); toggle(); }
if (e.ctrlKey && e.key === 'l' && isOpen) { e.preventDefault(); document.getElementById('osiris-clear-btn').click(); }
if (e.key === 'Escape' && isOpen) { toggle(false); }
});
buildOverlay();
console.log('%c🔺 OsirisAI Live Multilang yüklendi — Ctrl+Shift+E', 'color:#ff5a00;font-weight:bold;font-size:12px;');
})();