您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shows ratelimit information on Grok
当前为
// ==UserScript== // @name Grok ratelimit indicator // @namespace https://6942020.xyz/ // @version 1.3 // @description Shows ratelimit information on Grok // @author WadeGrimridge // @match https://grok.com/* // @license MIT // @grant none // ==/UserScript== (function () { "use strict"; const CONFIG = { MAX_RETRIES: 10, RETRY_DELAY: 1000, RATE_LIMIT_ENDPOINT: "/rest/rate-limits", REQUEST_KINDS: ["DEFAULT", "REASONING", "DEEPSEARCH", "DEEPERSEARCH"], MODELS: { "grok-3": { DEFAULT: "Grok 3", REASONING: "Think", DEEPSEARCH: "DeepSearch", DEEPERSEARCH: "DeeperSearch", }, }, }; const state = { rateInfoElement: null, modelRateLimits: { "grok-3": { DEFAULT: null, REASONING: null, DEEPSEARCH: null, DEEPERSEARCH: null, }, }, }; const formatTime = (seconds) => { const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const remainingSeconds = seconds % 60; if (hours > 0) { return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`; } return remainingSeconds > 0 ? `${minutes}m ${remainingSeconds}s` : `${minutes}m`; }; const isValidRateData = (data) => data && typeof data.remainingQueries === "number" && typeof data.totalQueries === "number" && typeof data.windowSizeSeconds === "number"; const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const fetchRateLimit = async ( modelName, requestKind = "DEFAULT", attempt = 1 ) => { try { const response = await fetch(CONFIG.RATE_LIMIT_ENDPOINT, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ requestKind, modelName }), }); if (response.status !== 200 && attempt <= CONFIG.MAX_RETRIES) { await sleep(CONFIG.RETRY_DELAY); return fetchRateLimit(modelName, requestKind, attempt + 1); } const data = await response.json(); if (!isValidRateData(data)) return; updateRateInfo(data, modelName, requestKind); } catch (error) { console.error("[grok-ratelimit] Rate limit fetch failed:", error); if (attempt > CONFIG.MAX_RETRIES && state.rateInfoElement) { state.rateInfoElement.textContent = "Couldn't fetch ratelimit info"; } } }; const formatRateLimitLine = (data, displayName) => { const timeStr = formatTime(data.windowSizeSeconds); return `${displayName}: ${data.remainingQueries}/${data.totalQueries} (${timeStr})`; }; const updateRateInfo = (data, modelName, requestKind = "DEFAULT") => { if (!state.rateInfoElement) return; state.modelRateLimits[modelName][requestKind] = data; const lines = []; CONFIG.REQUEST_KINDS.forEach((kind) => { const modelData = state.modelRateLimits["grok-3"][kind]; if (modelData) { lines.push( formatRateLimitLine(modelData, CONFIG.MODELS["grok-3"][kind]) ); } }); state.rateInfoElement.textContent = lines.join(" | "); }; const interceptFetch = () => { const originalFetch = window.fetch; window.fetch = async function (...args) { const [resource, options] = args; const url = resource instanceof Request ? resource.url : resource.toString(); if (!url.includes(CONFIG.RATE_LIMIT_ENDPOINT)) { return originalFetch.apply(this, args); } const response = await originalFetch.apply(this, args); const { modelName, requestKind } = JSON.parse(options.body); const clone = response.clone(); clone.json().then((data) => { if (isValidRateData(data)) { updateRateInfo(data, modelName, requestKind); } }); return response; }; }; const createRateInfoElement = () => { const targetDiv = document.querySelector( 'main div:has(> a[aria-label="Home page"])' ); if (!targetDiv || state.rateInfoElement) return; const headerDiv = targetDiv.parentElement; headerDiv.classList.remove( "@[80rem]/nav:h-0", "@[80rem]/nav:top-8", "@[80rem]/nav:from-transparent", "@[80rem]/nav:via-transparent" ); state.rateInfoElement = document.createElement("div"); state.rateInfoElement.className = "ml-2 text-sm break-words"; state.rateInfoElement.style.maxWidth = "calc(100vw - 240px)"; state.rateInfoElement.textContent = "Fetching ratelimit info..."; targetDiv.appendChild(state.rateInfoElement); initializeRateLimits(); }; const initializeRateLimits = async () => { await fetchRateLimit("grok-3", "DEFAULT"); for (const kind of CONFIG.REQUEST_KINDS.slice(1)) { await sleep(100); await fetchRateLimit("grok-3", kind); } }; const waitForElement = () => { const targetDiv = document.querySelector( 'main div:has(> a[aria-label="Home page"])' ); if (targetDiv) { createRateInfoElement(); } else { requestAnimationFrame(waitForElement); } }; interceptFetch(); waitForElement(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址