autoreg-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
119
skills/openai-team-proxy/SKILL.md
Normal file
119
skills/openai-team-proxy/SKILL.md
Normal file
@@ -0,0 +1,119 @@
|
||||
---
|
||||
name: openai-team-proxy
|
||||
description: Set up, run, rotate, and debug OpenAI Team OAuth proxy — round-robin balancer for opencode/Hermes with 67+ accounts, auto-refresh, and billing diagnosis.
|
||||
---
|
||||
|
||||
# OpenAI Team Proxy
|
||||
|
||||
Round-robin балансировщик OpenAI Team OAuth-аккаунтов. Прокси на `:20130`, совместим с OpenAI API (opencode, Kilo, Hermes, любой OpenAI-compatible клиент).
|
||||
|
||||
## Триггеры
|
||||
- Пользователь прислал ZIP/JSON с team-аккаунтами OpenAI
|
||||
- Нужно поднять прокси для opencode/Kilo/Hermes
|
||||
- Ключи протухли — нужна ротация
|
||||
- `billing_not_active` / `429` на team-аккаунтах
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
```bash
|
||||
cd openai-team
|
||||
pip install -r requirements.txt
|
||||
cp /path/to/batch.json current_batch.json
|
||||
python -u proxy.py # -u обязательно на Windows для HTTP серверов
|
||||
```
|
||||
|
||||
Проверка:
|
||||
```bash
|
||||
curl http://127.0.0.1:20130/health
|
||||
# → {"status":"ok","accounts":67,"concurrency":670}
|
||||
```
|
||||
|
||||
## Архитектура
|
||||
|
||||
- **proxy.py** — FastAPI + httpx, round-robin по аккаунтам, semaphore на concurrency
|
||||
- **current_batch.json** — файл с OAuth-токенами (gitignore)
|
||||
- **rotate.sh** — копирует новый батч + шлёт POST /reload
|
||||
- Порт: `20130` (настраивается через `PORT` env)
|
||||
- Прокси: `PROXY=socks5://user:pass@host:port` для исходящих
|
||||
|
||||
## Модели
|
||||
|
||||
Team-аккаунты дают доступ к: `gpt-5.2`, `gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-image-2`.
|
||||
|
||||
## Интеграция с opencode/Kilo
|
||||
|
||||
```jsonc
|
||||
"openai_team": {
|
||||
"npm": "@ai-sdk/openai-compatible",
|
||||
"options": {
|
||||
"baseURL": "http://127.0.0.1:20130/v1",
|
||||
"apiKey": "sk-bypass"
|
||||
},
|
||||
"models": {
|
||||
"gpt-5.6-terra": { "name": "gpt-5.6-terra" },
|
||||
"gpt-5.4-mini": { "name": "gpt-5.4-mini" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Ротация ключей (~10 дней)
|
||||
|
||||
```bash
|
||||
./rotate.sh /path/to/new_batch.json
|
||||
# или вручную:
|
||||
cp new.json current_batch.json && curl -X POST http://127.0.0.1:20130/reload
|
||||
```
|
||||
|
||||
## Питфолы
|
||||
|
||||
### BILLING_NOT_ACTIVE (HTTP 429 body)
|
||||
**ВСЕ 67 аккаунтов под одним workspace → биллинг общий.** Если workspace без карты — блокировка на всех. HTTP статус приходит 429, но тело содержит `billing_not_active`. Не путать с рейт-лимитом.
|
||||
|
||||
**Проверка:** прямой запрос к `https://api.openai.com/v1/chat/completions` с токеном и org_id. Если 429 + billing_not_active на нескольких раскиданных аккаунтах (напр. [0, 10, 20, 30, 40, 50, 60]) — проблема в workspace, не в отдельных токенах.
|
||||
|
||||
**Решение:** зайти в workspace на chatgpt.com → Billing → добавить карту.
|
||||
|
||||
### Refresh tokens — одноразовые
|
||||
Refresh-токены в батче ОДНОРАЗОВЫЕ. После первого использования (`POST https://auth.openai.com/oauth/token`) — сгорают с ошибкой `refresh_token_reused`. Прокси использует их при 401, после чего полагается только на access_token.
|
||||
|
||||
### OAuth access_token — реальный JWT, не обрезан
|
||||
В батчах `verify-jwt` access_token выглядит как `eyJhbG...bLiA` в read_file, но это артефакт отображения — реальный токен 1700+ символов, полный JWT. Проверять через `len(token)` в Python, не через read_file.
|
||||
|
||||
### Windows: python -u
|
||||
На Windows HTTP-серверы в фоне需要通过 `python -u` (unbuffered). Без `-u` вывод буферизируется и сервер кажется мёртвым.
|
||||
|
||||
### concurrency = сумма
|
||||
Каждый аккаунт имеет `concurrency: 10`. Общий semaphore = сумма всех concurrency (670 для 67 аккаунтов). Не путать с числом аккаунтов.
|
||||
|
||||
## Диагностика
|
||||
|
||||
```bash
|
||||
# Статус
|
||||
curl http://127.0.0.1:20130/health
|
||||
|
||||
# Модели
|
||||
curl http://127.0.0.1:20130/v1/models
|
||||
|
||||
# Тестовый запрос
|
||||
curl -s http://127.0.0.1:20130/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"gpt-5.4-mini","messages":[{"role":"user","content":"hi"}],"max_tokens":5}'
|
||||
|
||||
# Прямая проверка токенов (Python)
|
||||
python -c "
|
||||
import json, httpx, asyncio
|
||||
async def test():
|
||||
with open('current_batch.json') as f:
|
||||
data = json.load(f)
|
||||
for idx in [0, 10, 20, 30, 40, 50, 60, 66]:
|
||||
a = data['accounts'][idx]
|
||||
async with httpx.AsyncClient(timeout=30) as c:
|
||||
r = await c.post('https://api.openai.com/v1/chat/completions',
|
||||
headers={'Authorization': f'Bearer {a[\"credentials\"][\"access_token\"]}',
|
||||
'OpenAI-Organization': a['credentials']['organization_id'],
|
||||
'Content-Type': 'application/json'},
|
||||
json={'model':'gpt-5.4-mini','messages':[{'role':'user','content':'hi'}],'max_tokens':5})
|
||||
print(f'[{idx}] {a[\"name\"]:20s} | HTTP {r.status_code} | {r.json().get(\"error\",{}).get(\"message\",\"N/A\")}')
|
||||
asyncio.run(test())
|
||||
"
|
||||
```
|
||||
31
skills/openai-team-proxy/references/billing-not-active.md
Normal file
31
skills/openai-team-proxy/references/billing-not-active.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Billing Not Active — diagnostic transcript
|
||||
|
||||
## Symptom
|
||||
ALL 67 accounts under one workspace return identical error:
|
||||
```
|
||||
HTTP 429 Too Many Requests
|
||||
{"error":{"message":"Your account is not active, please check your billing details on our website.","type":"billing_not_active","code":"billing_not_active"}}
|
||||
```
|
||||
|
||||
## Root cause
|
||||
Workspace `rebeccaberger717419_outlook.com` (id: `708980e0-b4d9-4ceb-89e0-0b196d2f39fc`) has no payment method. All 67 accounts share the same `chatgpt_account_id` → billing is workspace-level → one missing card blocks everything.
|
||||
|
||||
## Diagnostic pattern
|
||||
Test 8 accounts spread across the full range [0, 10, 20, 30, 40, 50, 60, 66]. If ALL return billing_not_active → workspace issue, not individual account issue.
|
||||
|
||||
## Refresh token state
|
||||
Refresh tokens are one-time-use. After first refresh, they return:
|
||||
```
|
||||
HTTP 401
|
||||
{"error":{"message":"Your refresh token has already been used to generate a new access token. Please try signing in again.","code":"refresh_token_reused"}}
|
||||
```
|
||||
|
||||
## Access token format
|
||||
Tokens in `verify-jwt` batch are full 1700+ char JWTs. `read_file` truncates display with `...` but `len(token)` in Python confirms full length. Tokens authenticate successfully (200 on /v1/models, 401/429 on chat).
|
||||
|
||||
## Image generation
|
||||
`gpt-image-2` returns 401 with missing scopes — requires specific role/permission in workspace:
|
||||
```
|
||||
HTTP 401
|
||||
{"error":{"message":"You have insufficient permissions for this operation. Missing scopes: api.model.images.request..."}}
|
||||
```
|
||||
Reference in New Issue
Block a user