Skip to content

feat(provider): 支持 Claude 第三方 Coding Plan 配额对接#12

Open
MVP2142 wants to merge 5 commits into
stormzhang:mainfrom
MVP2142:feature_provider_v0.4.5
Open

feat(provider): 支持 Claude 第三方 Coding Plan 配额对接#12
MVP2142 wants to merge 5 commits into
stormzhang:mainfrom
MVP2142:feature_provider_v0.4.5

Conversation

@MVP2142

@MVP2142 MVP2142 commented Jun 25, 2026

Copy link
Copy Markdown

Summary

通过 API Key 使用第三方平台(如 OpenCode)时,CC 不会自动注入配额数据,状态栏看不到 5h/7d/月用量。本 PR 新增可扩展的 Provider 架构,支持外部脚本注入配额数据并在状态栏和 tt status 中显示。

效果样例

5765d1b9b539e0a5a1ab53cc095fdbd9

Changes

Provider 架构(新增 3 文件)

  • adapters/providers/base.pyRateProvider 抽象基类、ProviderRateData 中间格式、@register_provider 装饰器注册表、文件缓存(~/.cache/token-tracker/,TTL 控制)
  • adapters/providers/script.pyScriptProvider,通过 subprocess 执行用户配置的外部脚本,解析 stdout JSON,支持超时和缓存命中
  • adapters/providers/__init__.py — 导出工厂函数 create_provider(),自动发现已注册 provider

链式配额查询(修改 2 文件)

  • adapters/types.pyRateLimits 增加 monthly_pct / monthly_resets_at 字段
  • adapters/rate_limits.pyload_rate_limits() 改为链式查询:官方配额 > 第三方 provider > 官方 fallback;支持 model overlay(官方有模型名但无配额时,模型名覆盖 provider 结果)

CLI 诊断 & 状态栏联动(修改 2 文件)

  • cli.py — 新增 tt quota 诊断命令,输出配置/官方/第三方状态;--debug 显示脱敏配置详情;自动触发状态栏脚本重烘焙
  • hooks.py — CC statusline 脚本内嵌 provider fallback(官方无配额时自动调用 load_rate_limits());修复 settings.json 陈旧脚本路径的自动检测 + 修正(_cc_settings_path_stale, _fix_cc_settings_path

文档(修改 2 文件)

  • README.md / README_EN.md — 新增「第三方配额对接」章节

测试(新增 1 文件)

  • tests/test_providers.py — 19 个用例覆盖注册/缓存/超时/非法 JSON/退出码/链式优先级/model overlay

配置方式

创建 ~/.claude/tt-config.json

{
  "rate_provider": {
    "type": "script",
    "command": "python ~/.claude/tt-opencode-quota.py",
    "cache_ttl": 60,
    "timeout": 10
  }
}
字段 默认值 说明
type 固定为 script
command 要执行的命令
cache_ttl 60 缓存秒数
timeout 10 脚本执行超时秒数

脚本输出格式

自定义脚本需输出以下 JSON 到 stdout(各窗口字段均可选):

{
  "five_hour": {
    "used_percentage": 31.5,
    "resets_at": 1718457600
  },
  "seven_day": {
    "used_percentage": 12.3,
    "resets_at": 1718889600
  },
  "monthly": {
    "used_percentage": 8.7,
    "resets_at": 1719753600
  },
  "source": "OpenCode"
}
  • used_percentage — 已用百分比(0-100)
  • resets_at — UTC 时间戳,重置时间
  • source — 来源标识,显示在 tt status 和状态栏中

OpenCode 脚本样例

创建 ~/.claude/tt-opencode-quota.py

#!/usr/bin/env python3
"""OpenCode 用量查询:GET workspace 页面 HTML,正则提取三项用量。"""
import json, re, time, urllib.request, sys

WORKSPACE_ID = "wrk_xxxxxxxxxxxxxxxxxxxxxxxx"
AUTH_COOKIE = "Fe26.2**xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
PAGE_URL = f"https://opencode.ai/workspace/{WORKSPACE_ID}/go"


def fetch_usage():
    req = urllib.request.Request(PAGE_URL)
    req.add_header("cookie", f"oc_locale=en; auth={AUTH_COOKIE.strip()}")
    req.add_header("user-agent",
                   "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
                   "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36")
    with urllib.request.urlopen(req, timeout=15) as resp:
        return resp.read().decode()


def parse(html):
    secs = re.findall(r"resetInSec:(\d+)", html)
    pcts = re.findall(r"usagePercent:([\d.]+)", html)
    if len(secs) < 3 or len(pcts) < 3:
        raise ValueError("解析失败,cookie 可能已过期")
    return secs[:3], pcts[:3]


def main():
    now = int(time.time())
    try:
        html = fetch_usage()
        secs, pcts = parse(html)
        rolling_s, weekly_s, monthly_s = (int(s) for s in secs)
        rolling_p, weekly_p, monthly_p = (float(p) for p in pcts)
        print(json.dumps({
            "five_hour": {"used_percentage": round(rolling_p, 1), "resets_at": now + rolling_s},
            "seven_day": {"used_percentage": round(weekly_p, 1), "resets_at": now + weekly_s},
            "monthly": {"used_percentage": round(monthly_p, 1), "resets_at": now + monthly_s},
            "source": "OpenCode",
        }))
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()

auth cookie 使用 Fe26.2 加密,会过期。失效后重新从浏览器复制。

诊断命令

tt quota           # 查看配额状态和提供者信息
tt quota --debug   # 显示脱敏后的配置详情

数据优先级

官方注入配额(CC 订阅模式)> 第三方 provider > 官方仅模型信息(fallback)。CC 状态栏在检测到无官方配额时自动走 provider 链式查询。


Test

143 passed in 2.07s

MVP2142 added 5 commits June 25, 2026 14:14
CC 自 0.4.5 开始在 statusLine payload 中上报配额数据后,
load_rate_limits() 因优先返回官方数据,导致第三方提供者(如
opencode)的配额值一直被跳过。状态栏脚本也同样只在 CC 未上报时
才查提供者。

修复:load_rate_limits() 改为提供者优先、官方降级;状态栏脚本
改为始终查询 load_rate_limits(),保证两边数据一致。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant