Gemini Model Memory

Automatically select default model. Remembers user's choice across app, notebook, and gem pages.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

You will need to install an extension such as Tampermonkey to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         Gemini Model Memory
// @namespace    http://greatest.deepsurf.us/
// @version      2.1
// @description  Automatically select default model. Remembers user's choice across app, notebook, and gem pages.
// @author       Bui Quoc Dung
// @match        https://gemini.google.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    if (window.self !== window.top) return;


    const siteConfig = {
        targetPaths: ['app', 'notebook', 'gem'],
        selectors: {
            pickerBtn: 'button[data-test-id="bard-mode-menu-button"]',
            menuItems: '[role="menuitemradio"], [role="menuitem"]'
        }
    };

    const timings = {
        interval: 1000,
        renderDelay: 600,
        cooldown: 1500
    };

    const MODELS = {
        0: { keywords: ["Flash-lite"] },
        1: { keywords: ["Flash"] },
        2: { keywords: ["Pro"] }
    };

    let savedIndex = localStorage.getItem('gemini_saved_model_index');
    let targetModelId = (savedIndex !== null && MODELS[savedIndex]) ? parseInt(savedIndex) : 1;

    let isSwitching = false;
    let userManualSelection = false;


    function isValidTargetPage() {
        const path = window.location.pathname;
        return siteConfig.targetPaths.some(target => {
            const regex = new RegExp(`\\/(${target})(\\/|$)`, 'i');
            return regex.test(path);
        });
    }

    document.addEventListener('click', (e) => {
        if (isSwitching) return;

        const pickerBtn = document.querySelector(siteConfig.selectors.pickerBtn);
        const item = e.target.closest(siteConfig.selectors.menuItems);

        if (item) {
            const itemText = item.innerText || item.textContent || "";
            for (let key in MODELS) {
                if (MODELS[key].keywords.some(k => itemText.includes(k))) {
                    targetModelId = parseInt(key);
                    localStorage.setItem('gemini_saved_model_index', key);
                    break;
                }
            }
            userManualSelection = false;
        } else if (pickerBtn && pickerBtn.contains(e.target)) {
            userManualSelection = true;
        } else {
            userManualSelection = false;
        }
    }, true);

    setInterval(() => {
        if (!isValidTargetPage() || isSwitching || userManualSelection) return;

        const pickerBtn = document.querySelector(siteConfig.selectors.pickerBtn);
        if (!pickerBtn) return;

        const currentText = pickerBtn.innerText || pickerBtn.textContent || "";
        const targetModel = MODELS[targetModelId];

        if (!targetModel) return;
        if (targetModel.keywords.some(k => currentText.includes(k))) return;

        isSwitching = true;
        pickerBtn.click();

        setTimeout(() => {
            const menuItems = document.querySelectorAll(siteConfig.selectors.menuItems);
            let clicked = false;

            for (let item of menuItems) {
                if (item.getBoundingClientRect().width > 0) {
                    const itemText = item.innerText || item.textContent || "";
                    if (targetModel.keywords.some(k => itemText.includes(k))) {
                        item.click();
                        clicked = true;
                        break;
                    }
                }
            }

            if (!clicked) document.body.click();

            setTimeout(() => {
                isSwitching = false;
            }, timings.cooldown);

        }, timings.renderDelay);
    }, timings.interval);

})();