• xufengjun130

    我现在手上有一个GPT200刀的套餐,这几天感觉额度比以前要更耐用了,不知道是什么原因,就像看看现在是有多少额度,佬们有没有什么比较好用的,计算codex额度的插件,这个账号是我和我朋友一起公用的菲区账号,所以直接计算我电脑消耗的token不太准确,希望有可以直接通过查看 新建标签页来获得较为准确额度的插件,谢谢佬了

    主楼
  • T_T

    你可以让codex帮你统计上一次重置的日期到你现在的使用量 然后推导出用量 网页那个有延迟的 不准

    #1
  • xufengjun130

    现在问题就是账号是两人共用的,我只能计算我使用的额度,无法计算账号的额度

    #2
  • 猫建国
    // ==UserScript==
    // @name         Codex Quota Compass (Visual Edition)
    // @namespace    http://tampermonkey.net/
    // @version      1.8
    // @description  人性化展示 Codex 配额,强化 Credits 标注,增加历史合计及动态日期范围(Token 以 M 为单位)
    // @author       Jun Zhao
    // @match        https://chatgpt.com/codex/cloud/settings/analytics*
    // @grant        GM_addStyle
    // ==/UserScript==
    
    (function () {
      "use strict";
    
      const CONFIG = {
        USD_PER_CREDIT: 40 / 1000,
      };
    
      // 修改:将中文的“亿/万”单位替换为国际标准的“M/K”单位
      const fmtNum = (n) => {
        if (n >= 1e6) return (n / 1e6).toFixed(2) + "M";
        if (n >= 1e3) return (n / 1e3).toFixed(2) + "K";
        return n.toLocaleString();
      };
    
      const n = (v) => (Number.isFinite(Number(v)) ? Number(v) : 0);
      const tokenTotal = (obj = {}) =>
        n(obj.text_total_tokens) ||
        n(obj.cached_text_input_tokens) +
          n(obj.uncached_text_input_tokens) +
          n(obj.text_output_tokens);
    
      GM_addStyle(`
            #codex-compass-root {
                position: fixed; top: 5%; left: 50%; transform: translateX(-50%);
                width: 720px; max-height: 90vh; background: #fff;
                border-radius: 12px; box-shadow: 0 10px 50px rgba(0,0,0,0.3);
                z-index: 10001; padding: 24px; display: none;
                flex-direction: column; border: 1px solid #e5e5e5; color: #333;
                font-family: -apple-system, system-ui, sans-serif;
            }
            .compass-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; }
            .compass-title { font-size: 18px; font-weight: 600; }
            .compass-close { cursor: pointer; font-size: 28px; color: #999; line-height: 1; }
            .compass-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 20px; }
            .compass-card { background: #f9f9f9; padding: 12px; border-radius: 8px; border: 1px solid #eee; }
            .compass-card.highlight { background: #eefaf5; border-color: #d1f2e1; }
            .card-label { font-size: 12px; color: #666; margin-bottom: 4px; }
            .card-value { font-size: 15px; font-weight: bold; color: #10a37f; white-space: nowrap; }
    
            .table-container {
                max-height: 220px; overflow-y: auto; border: 1px solid #eee;
                border-radius: 6px; margin-bottom: 15px;
            }
            .compass-table { width: 100%; border-collapse: collapse; font-size: 12px; }
            .compass-table thead { position: sticky; top: 0; background: #f5f5f5; z-index: 1; }
            .compass-table th { text-align: left; padding: 8px; border-bottom: 1px solid #eee; color: #666; }
            .compass-table td { padding: 8px; border-bottom: 1px solid #f0f0f0; }
            .compass-footer-row { background: #fafafa; font-weight: bold; position: sticky; bottom: 0; border-top: 2px solid #eee; }
    
            #codex-compass-btn {
                position: fixed; bottom: 20px; right: 20px; z-index: 10000;
                padding: 10px 20px; background: #10a37f; color: white;
                border: none; border-radius: 8px; cursor: pointer; font-weight: 600;
            }
        `);
    
      async function apiGet(path, token) {
        const res = await fetch(path, {
          headers: { Authorization: `Bearer ${token}` },
        });
        return res.json();
      }
    
      const showPanel = (data) => {
        const root = document.getElementById("codex-compass-root");
        const { secondary, dailyList, cycleStartDate } = data;
    
        // 1. 数据切分
        const currentCycleList = [];
        const historyList = [];
        dailyList.forEach((item) => {
          if (new Date(item.date) >= new Date(cycleStartDate)) {
            currentCycleList.push(item);
          } else {
            historyList.push(item);
          }
        });
    
        // 2. 统计计算辅助函数
        const getStats = (list) => {
          const credits = list.reduce(
            (sum, d) => sum + (d.totals?.credits || 0),
            0,
          );
          const turns = list.reduce((sum, d) => sum + (d.totals?.turns || 0), 0);
          const tokens = list.reduce((sum, d) => sum + tokenTotal(d.totals), 0);
          return { credits, turns, tokens, usd: credits * CONFIG.USD_PER_CREDIT };
        };
    
        const currentStats = getStats(currentCycleList);
        const historyStats = getStats(historyList);
    
        const ratio = (secondary?.used_percent || 0) / 100;
        const estCredits =
          ratio > 0 ? (currentStats.credits / ratio).toFixed(1) : "0";
    
        // 3. 历史记录日期范围计算
        let historyRangeTitle = "⏳ 历史记录 (本周期外)";
        if (historyList.length > 0) {
          const sortedHistory = [...historyList].sort(
            (a, b) => new Date(a.date) - new Date(b.date),
          );
          const startStr = sortedHistory[0].date;
          const endStr = sortedHistory[sortedHistory.length - 1].date;
          historyRangeTitle = `⏳ 历史记录 (本周期外 ${endStr} 至 ${startStr})`;
        }
    
        const renderTable = (list, stats) => `
                <div class="table-container">
                    <table class="compass-table">
                        <thead>
                            <tr><th>日期</th><th>Credits</th><th>Tokens</th><th>金额</th><th>轮数</th></tr>
                        </thead>
                        <tbody>
                            ${[...list]
                              .reverse()
                              .map(
                                (row) => `
                                <tr>
                                    <td>${row.date}</td>
                                    <td style="font-family:monospace">${(row.totals?.credits || 0).toFixed(3)}</td>
                                    <td style="font-family:monospace">${fmtNum(tokenTotal(row.totals))}</td>
                                    <td>$ ${((row.totals?.credits || 0) * CONFIG.USD_PER_CREDIT).toFixed(2)}</td>
                                    <td>${row.totals?.turns || 0}</td>
                                </tr>
                            `,
                              )
                              .join("")}
                        </tbody>
                        <tfoot>
                            <tr class="compass-footer-row">
                                <td>合计</td>
                                <td>${stats.credits.toFixed(3)}</td>
                                <td style="font-family:monospace">${fmtNum(stats.tokens)}</td>
                                <td style="color:#10a37f">$ ${stats.usd.toFixed(2)}</td>
                                <td>${stats.turns}</td>
                            </tr>
                        </tfoot>
                    </table>
                </div>
            `;
    
        root.innerHTML = `
                <div class="compass-header">
                    <div class="compass-title">📊 Codex 配额深度分析 (V1.8)</div>
                    <div class="compass-close" id="compass-close-btn">&times;</div>
                </div>
                <div class="compass-grid">
                    <div class="compass-card">
                        <div class="card-label">已用比例</div>
                        <div class="card-value">${secondary?.used_percent || 0}%</div>
                    </div>
                    <div class="compass-card">
                        <div class="card-label">本周已用</div>
                        <div class="card-value">${currentStats.credits.toFixed(1)} <span style="font-size:10px; font-weight:normal">Credits</span></div>
                    </div>
                    <div class="compass-card highlight">
                        <div class="card-label">推算总额</div>
                        <div class="card-value">${estCredits} <span style="font-size:10px; font-weight:normal">Credits</span></div>
                    </div>
                    <div class="compass-card">
                        <div class="card-label">周价值 (估算)</div>
                        <div class="card-value">$ ${(estCredits * CONFIG.USD_PER_CREDIT).toFixed(2)}</div>
                    </div>
                </div>
    
                <div style="font-weight:600; margin-bottom:8px; font-size:13px;">📅 本周期明细 (始于 ${cycleStartDate})</div>
                ${renderTable(currentCycleList, currentStats)}
    
                ${
                  historyList.length > 0
                    ? `
                <div style="font-weight:600; margin-bottom:8px; font-size:13px; color: #666; margin-top: 5px;">${historyRangeTitle}</div>
                ${renderTable(historyList, historyStats)}
                `
                    : ""
                }
            `;
    
        root.style.display = "flex";
        document.getElementById("compass-close-btn").onclick = () =>
          (root.style.display = "none");
      };
    
      const run = async () => {
        const btn = document.getElementById("codex-compass-btn");
        const bootstrapData =
          document.getElementById("client-bootstrap")?.textContent;
        const token = bootstrapData?.match(
          /[\w-]{30,}\.[\w-]{30,}\.[\w-]{30,}/,
        )?.[0];
        if (!token) return alert("令牌获取失败,请确保已登录。");
    
        btn.innerText = "分析中...";
        try {
          const usage = await apiGet("/backend-api/wham/usage", token);
          const secondary =
            usage?.rate_limit?.secondary_window ||
            usage?.rate_limit?.primary_window;
    
          const endDate = new Date(Date.now() + 86400000)
            .toISOString()
            .split("T")[0];
          const startDate = new Date(Date.now() - 30 * 86400000)
            .toISOString()
            .split("T")[0];
          const cycleStartDate = secondary
            ? new Date((secondary.reset_at - secondary.limit_window_seconds) * 1000)
                .toISOString()
                .split("T")[0]
            : startDate;
    
          const dailyData = await apiGet(
            `/backend-api/wham/analytics/daily-workspace-usage-counts?start_date=${startDate}&end_date=${endDate}&group_by=day`,
            token,
          );
    
          showPanel({ secondary, dailyList: dailyData.data || [], cycleStartDate });
        } catch (e) {
          alert("错误: " + e.message);
        } finally {
          btn.innerText = "📊 运行用量分析";
        }
      };
    
      const btn = document.createElement("button");
      btn.id = "codex-compass-btn";
      btn.innerText = "📊 运行用量分析";
      btn.onclick = run;
      document.body.appendChild(btn);
    
      const root = document.createElement("div");
      root.id = "codex-compass-root";
      document.body.appendChild(root);
    })();
    ```之前别的佬友发的,可以试试。
    #3
  • Edge

    因为很慢,我开Fast都只有40T/s,根本用不出去

    #4
  • T_T

    那个网页用量延迟很大 不准 最准的就是两个人用量累计 现在一般就 1300 左右

    #5
  • 猫建国

    图片

    羡慕佬友的额度,我的20x额度大幅度缩水,完全不够用

    #6
  • xufengjun130

    图片

    看来是正常的,之前的额度是缩水的

    #7
  • xufengjun130

    佬,你这额度直接变成plus了啊,这也太少了

    #8
  • 猫建国

    是啊,上个周期还正常,今天早上用了重置卡后额度就大幅度缩水。

    看看明天tibo重置后额度变化吧。^-^

    #9
  • xufengjun130

    听说又要重置额度了,现在额度还有44%,要用不完了

    #10
  • 吃风筝的人

    被codex desktop subagent意外耗尽了额度, 现在已经开始烧credits了

    #11
  • Jeeringly

    这个我看现在都有5.6版本了,也不知道哪个版本准。

    图片

    #12
  • xufengjun130

    我去,佬,这个版本能发一下嘛,我看看是怎么个事

    #13
  • Jeeringly

    这个帖子里面的 完全准确查询你的GPT订阅周限的方法【油猴脚本】 - #313,来自 strand

    #14

发表回复

登录后回复