Grok ratelimit indicator

Shows ratelimit information on Grok

2025-03-24 या दिनांकाला. सर्वात नवीन आवृत्ती पाहा.

// ==UserScript==
// @name         Grok ratelimit indicator
// @namespace    https://6942020.xyz/
// @version      1.0
// @description  Shows ratelimit information on Grok
// @author       WadeGrimridge
// @match        https://grok.com/*
// @license      MIT
// @grant        none
// ==/UserScript==

(function () {
  "use strict";

  let rateInfoElement = null;
  const modelRateLimits = {
    "grok-latest": null,
    "grok-3": null,
  };
  const modelDisplayNames = {
    "grok-latest": "Grok 2",
    "grok-3": "Grok 3",
  };

  function formatTime(seconds) {
    const minutes = Math.floor(seconds / 60);
    const remainingSeconds = seconds % 60;
    return remainingSeconds > 0
      ? `${minutes}m ${remainingSeconds}s`
      : `${minutes}m`;
  }

  async function fetchRateLimit(modelName, attempt = 1) {
    try {
      const response = await fetch("/rest/rate-limits", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ requestKind: "DEFAULT", modelName }),
      });

      if (response.status === 401 && attempt <= 10) {
        await new Promise((resolve) => setTimeout(resolve, 2500));
        return fetchRateLimit(modelName, attempt + 1);
      }

      const data = await response.json();
      if (
        data.remainingQueries !== undefined &&
        data.totalQueries !== undefined
      ) {
        updateRateInfo(data, modelName);
      }
    } catch (error) {
      console.error(`[grok-ratelimit] Rate limit fetch failed:`, error);
      if (attempt > 10 && rateInfoElement) {
        rateInfoElement.textContent = "Couldn't fetch ratelimit info";
      }
    }
  }

  function createRateInfoElement() {
    const targetDiv = document.querySelector(
      'main div:has(> a[aria-label="Home page"])'
    );
    if (targetDiv && !rateInfoElement) {
      rateInfoElement = document.createElement("div");
      rateInfoElement.className = "ml-2 text-sm";
      rateInfoElement.textContent = "Fetching ratelimit info...";
      targetDiv.appendChild(rateInfoElement);

      (async () => {
        await fetchRateLimit("grok-3");
        await fetchRateLimit("grok-latest");
      })();
    }
  }

  function updateRateInfo(data, modelName) {
    if (rateInfoElement) {
      modelRateLimits[modelName] = data;

      const lines = [];
      const displayOrder = ["grok-3", "grok-latest"];

      for (const model of displayOrder) {
        const data = modelRateLimits[model];
        if (data) {
          const timeStr = formatTime(data.windowSizeSeconds);
          lines.push(
            `${modelDisplayNames[model]}: ${data.remainingQueries}/${data.totalQueries} (${timeStr})`
          );
        }
      }

      rateInfoElement.textContent = lines.join(" | ");
    }
  }

  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("/rest/rate-limits")) {
      const requestBody = JSON.parse(options.body);
      const modelName = requestBody.modelName;

      const response = await originalFetch.apply(this, args);
      const clone = response.clone();
      clone.json().then((data) => {
        if (
          data.remainingQueries !== undefined &&
          data.totalQueries !== undefined
        ) {
          updateRateInfo(data, modelName);
        }
      });
      return response;
    }

    return originalFetch.apply(this, args);
  };

  function waitForElement() {
    const targetDiv = document.querySelector(
      'main div:has(> a[aria-label="Home page"])'
    );
    if (targetDiv) {
      createRateInfoElement();
    } else {
      requestAnimationFrame(waitForElement);
    }
  }

  waitForElement();
})();