Auto retry when server busy detected by text or SVG icon, with toggle UI and cooldown.
当前为
// ==UserScript==
// @name DeepSeek Auto-Retry with Text & SVG Detection
// @version 1.2
// @description Auto retry when server busy detected by text or SVG icon, with toggle UI and cooldown.
// @author Blakken
// @match https://chat.deepseek.com/*
// @grant none
// @license MIT
// @namespace https://greasyfork.org/users/1477546
// ==/UserScript==
(function () {
"use strict";
const config = {
autoRetryEnabled: true,
cooldown: 15000, // 15 secondes entre retries
interval: 1000, // vérifie toutes les 1 seconde
errorTexts: [
"Server busy, please try again later.",
"The server is busy. Please try again later.",
"Thought for 0 seconds",
],
};
// Retourne vrai si un texte contient un message d'erreur
function isErrorText(text) {
return config.errorTexts.some(msg => text.includes(msg));
}
// Vérifie la présence d'un SVG orange spécifique dans un block
function blockHasBusySVG(block) {
const path = block.querySelector("svg path");
if (!path) return false;
const d = path.getAttribute("d") || "";
const fill = path.getAttribute("fill") || "";
const pathStart = "M12 .5C18.351.5 23.5 5.649 23.5 12S18.351 23.5";
return d.startsWith(pathStart) && fill.toLowerCase() === "#f59e0b";
}
// Trouve le bouton retry par détection SVG orange dans les boutons
function findRetryButton() {
const buttons = document.querySelectorAll("div.ds-icon-button");
const pathStart = "M12 .5C18.351.5 23.5 5.649 23.5 12S18.351 23.5";
for (let i = buttons.length - 1; i >= 0; i--) {
const btn = buttons[i];
const path = btn.querySelector("svg path");
if (!path) continue;
const d = path.getAttribute("d") || "";
const fill = path.getAttribute("fill") || "";
if (d.startsWith(pathStart) && fill.toLowerCase() === "#f59e0b") {
return btn;
}
}
return null;
}
// Cherche dans la page un message d'erreur textuel ou un SVG de busy
function detectErrors() {
// 1) Cherche les blocs avec texte d'erreur
const textBlocks = [...document.querySelectorAll("div.ac2694a7 span, div.ds-markdown.ds-markdown--block")];
for (const block of textBlocks) {
const text = block.innerText || "";
if (isErrorText(text)) return true;
}
// 2) Cherche les SVG d'icône busy dans les mêmes blocks (au cas où)
for (const block of textBlocks) {
if (blockHasBusySVG(block)) return true;
}
return false;
}
// Affiche un message visuel temporaire sur la page
function showStatus(msg) {
let el = document.getElementById("autoRetryStatus");
if (!el) {
el = document.createElement("div");
el.id = "autoRetryStatus";
el.style.position = "fixed";
el.style.bottom = "100px";
el.style.right = "20px";
el.style.backgroundColor = "rgba(0,0,0,0.7)";
el.style.color = "white";
el.style.padding = "6px 12px";
el.style.borderRadius = "6px";
el.style.zIndex = "9999";
document.body.appendChild(el);
}
el.textContent = msg;
setTimeout(() => {
if (el.textContent === msg) el.textContent = "";
}, 3000);
}
// Vérifie si erreur détectée et clique sur retry si cooldown passé
function checkAndRetry() {
if (!config.autoRetryEnabled) return;
if (!detectErrors()) return;
const now = Date.now();
if (window.lastRetryTime && now - window.lastRetryTime < config.cooldown) {
showStatus(`AutoRetry: cooldown (${Math.round((config.cooldown - (now - window.lastRetryTime))/1000)}s left)`);
return;
}
const retryBtn = findRetryButton();
if (retryBtn) {
retryBtn.click();
window.lastRetryTime = now;
showStatus("AutoRetry: Retry clicked");
console.log("AutoRetry: retry button clicked");
} else {
showStatus("AutoRetry: Retry button NOT found");
console.log("AutoRetry: retry button NOT found");
}
}
// Créé le toggle UI ON/OFF pour l'auto-retry
function createToggleUI() {
const container = document.createElement("div");
container.id = "autoRetryToggleUI";
container.style.position = "fixed";
container.style.bottom = "70px";
container.style.right = "20px";
container.style.zIndex = "9999";
container.style.backgroundColor = "rgba(0,0,0,0.6)";
container.style.padding = "8px 12px";
container.style.borderRadius = "8px";
container.style.color = "white";
container.style.fontFamily = "Arial, sans-serif";
container.style.fontSize = "14px";
container.style.userSelect = "none";
container.innerHTML = `
<label style="cursor: pointer;">
<input type="checkbox" id="autoRetryCheckbox" checked style="margin-right:6px;">
Auto‑Retry
</label>
`;
document.body.appendChild(container);
document.getElementById("autoRetryCheckbox").addEventListener("change", e => {
config.autoRetryEnabled = e.target.checked;
showStatus(`Auto‑Retry turned ${config.autoRetryEnabled ? "ON" : "OFF"}`);
console.log(`Auto‑Retry turned ${config.autoRetryEnabled ? "ON" : "OFF"}`);
});
}
// Initialisation
function init() {
createToggleUI();
setInterval(checkAndRetry, config.interval);
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();