Feature/account id dedup and subscription api#560
Open
youyao666 wants to merge 16 commits into
Open
Conversation
# Conflicts: # app/products/openai/router.py # app/products/openai/video.py
1. quota_defaults: _SUPPORTED_MODE_IDS_BY_POOL 新增 "auto" 键(全集0-4), 修复 pool="auto" 导入时只 fetch fast 模式导致 infer_pool 把 super/heavy 误判为 basic 的问题。 2. router: chat/completions 视频流式结果不再跳过 _prime_sse, 空生成器会正确抛出 429 而非静默返回 HTTP 200 空 SSE。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: 按 account_id 去重 + Grok 官方账号类型查询 + Cookie 注入支持 核心变更: - 添加 account_id (xaiUserId) 字段到 AccountRecord, 实现基于账号唯一 ID 的去重, 相同 xaiUserId 的多个 SSO token 自动合并, 只保留最新一个 - 新增 xai_subscription.py 协议模块, 调用 /rest/subscriptions 获取官方账号类型 (SUBSCRIPTION_TIER_GROK_PRO → super, GROK_PRO_HEAVY → heavy) - 导入时自动探测订阅层级和 account_id, 配合 rate-limits API 交叉验证 - 三个存储后端 (SQL/Redis/SQLite) 全部支持 account_id 列和去重逻辑 - Redis 后端补全缺失的 quota_grok_4_3 字段 - 添加 /rest/subscriptions, /rest/products, /rest/modes 端点 - Admin tokens API 输出 account_id - 附带 inject_cookie.py 浏览器 Cookie 注入工具 Grok API 探索发现: - GET /rest/subscriptions → xaiUserId + tier + status - POST /rest/modes → 基于订阅的模式可用性 - GET /rest/products → 可用产品层级列表 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> @
Phase 1 (_refresh_subscription): set account_id + store sub_tier/sub_active in ext
Phase 2 (_refresh_one): multi-factor inference:
1. Primary: infer_pool from rate-limits auto.total (ground truth)
2. Fallback: if rate-limits says basic but active subscription says super/heavy,
subscription wins (paying customer = real super account)
3. For basic accounts, always fetch ALL modes to see auto.total
Scenarios:
auto=50, any sub -> super (rate-limits)
auto=7, INACTIVE -> basic (genuinely downgraded)
auto=N/A, ACTIVE sub -> super (API fluke, subscription wins)
auto=7, ACTIVE sub -> super (active sub > anomalous quota)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Use inferred pool for quota normalization so auto/expert/grok_4_3 modes fetched for basic accounts aren't discarded by normalize_quota_window (basic pool doesn't support those modes). Before: super accounts had auto=0 expert=0 (data fetched but thrown away) After: super accounts have auto=19137 expert=15212 (correctly preserved) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
723cda3 to
c0e31ad
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
三个改动:
同一个 xAI 账号换浏览器登录会产生不同 SSO token,但 xaiUserId 相同。原来只按 token
去重导致同一账号被重复导入、配额虚高。
原来靠 rate-limits 的 auto.total 间接猜层级(20=basic, 50=super,
150=heavy),配额窗口过期后显示不准。现在直接查官方接口拿 tier(SUBSCRIPTION_TIER_GROK_PRO → super, GROK_PRO_HEAVY →
heavy)和 xaiUserId,结果权威。
Redis 的 _to_hash / _from_hash 漏了 Grok 4.3 Beta 的配额字段,读写都会丢数据。
端对端(真实 Grok API + 服务运行):
1. 启动服务
uv sync && uv run granian --interface asgi --host 127.0.0.1 --port 8000 --workers 1 app.main:app &
2. 导入真实 SSO cookie
curl -X POST http://127.0.0.1:8000/admin/api/tokens/add
-H "Authorization: Bearer grok2api"
-H "Content-Type: application/json"
-d '{"tokens": ["eyJ0eXAiOiJKV1Qi..."], "pool": "auto"}'
→ {"status":"success","count":1,"synced":true}
3. 查看结果 — account_id 和 pool 已自动填充
curl http://127.0.0.1:8000/admin/api/tokens -H "Authorization: Bearer grok2api"
→ {"token":"eyJ...","account_id":"c4492aa9-be8b-449a-b349-18ecb459b3e6","pool":"super",
"quota":{"auto":{"remaining":48,"total":50},"fast":{"remaining":140,"total":140}...}}
4. Chat API 正常
curl -X POST http://127.0.0.1:8000/v1/chat/completions
-H "Content-Type: application/json"
-d '{"model":"grok-4.20-fast","messages":[{"role":"user","content":"hello"}]}'
→ 200 OK, choices[0].message.content: "Hello! 👋 ..."
潜在问题(已知):
Related
基于 grok2api (https://github.com/chenyme/grok2api) 的 Grok Web API 逆向成果: