autoreg-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
145
skills/plane-so-farm-gateway/PLANE_RUNBOOK.md
Normal file
145
skills/plane-so-farm-gateway/PLANE_RUNBOOK.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# PLANE.SO FARM + GATEWAY — RUNBOOK ДЛЯ АГЕНТА
|
||||
|
||||
> Полный цикл: фарм аккаунтов plane.so → OpenAI-совместимый шлюз для любых CLI.
|
||||
> Всё проверено живьём 2026-09-20. Файлы: `C:\Users\User\Desktop\_SCRIPTS\`
|
||||
|
||||
## АРХИТЕКТУРА (что под капотом)
|
||||
|
||||
```
|
||||
[plane_full_combo.py] фарм: email → magic-code → session → workspace → API token
|
||||
↓ plane_accounts.jsonl (FULL_OK записи)
|
||||
[plane_gw.py :20130] шлюз OpenAI-compat: пул акков, ротация, auto-disable
|
||||
↓
|
||||
pi.plane.so Plane AI API (FastAPI, openapi.json открыт)
|
||||
```
|
||||
|
||||
**Ключевые факты (реверс makeplane/plane preview + pi.plane.so/openapi.json):**
|
||||
- Backend: `api.plane.so` (НЕ app.plane.so — там только SPA, 405)
|
||||
- AI API: `pi.plane.so` — отдельный FastAPI-хост, auth = cookie `session-id`
|
||||
- Чат-флоу: `initialize-chat` → `queue-answer` → `stream-answer/{token}` (SSE)
|
||||
- Капчи НЕТ. Magic-code на email. Троттл auth: 10/min на IP
|
||||
- Кредиты: **105/день на аккаунт**, сброс 00:00 UTC (видно в `/api/v1/chat/start/auth-check/`)
|
||||
- Сессия живёт **7 дней** (Max-Age=604800)
|
||||
- 10 моделей: GPT-5.6 Terra, GPT-5.4, Claude Sonnet 5 / 4.6, GLM-5.3/5.3-Flash/5.2, Kimi-K3/K2.6, DeepSeek-V4-Pro
|
||||
|
||||
## ШАГ 1. ПОЧТА
|
||||
|
||||
Нужен IMAP-ящик с app-password. Gmail `+alias` работает (plane его не режет).
|
||||
Один ящик = бесконечные акки через `yourname+prNNNNNN@gmail.com`.
|
||||
|
||||
Заполни в `plane_full_combo.py` (секция CONFIG):
|
||||
```python
|
||||
IMAP_HOST = "imap.gmail.com"
|
||||
IMAP_USER = "..." # логин ящика
|
||||
IMAP_PASS = "..." # app password (не основной пароль)
|
||||
EMAIL_DOMAIN = "gmail.com"
|
||||
EMAIL_LOCAL = "..." # локальная часть для алиасов
|
||||
```
|
||||
|
||||
## ШАГ 2. ФАРМ АККАУНТОВ
|
||||
|
||||
```bash
|
||||
cd C:\Users\User\Desktop\_SCRIPTS
|
||||
|
||||
# один акк (тест):
|
||||
python plane_full_combo.py test1
|
||||
|
||||
# массово 50 акков (sleep 7s встроен под троттл):
|
||||
python plane_full_combo.py --bulk 50 plane_accounts.jsonl
|
||||
```
|
||||
|
||||
Каждый акк делает 10 шагов: email-check → magic-generate → IMAP читает код
|
||||
(subject "Your unique Plane login code is NNNNNN") → CSRF → sign-up → verify
|
||||
→ create workspace → API token → token live-check → JSONL.
|
||||
|
||||
**Успешная запись:** `"result": "FULL_OK"` + `session_cookie` + `workspace{slug,id}` + `api_token`.
|
||||
Всё остальное — пропуск (NO_OTP = письмо не дошло за 2 мин, GEN_FAIL = троттл, EXISTS = акк уже есть).
|
||||
|
||||
Результат: `~25 сек/акк`, выход `plane_accounts.jsonl` (append-режим, можно дофармливать).
|
||||
|
||||
## ШАГ 3. ЗАПУСК ШЛЮЗА
|
||||
|
||||
```bash
|
||||
cd C:\Users\User\Desktop\_SCRIPTS
|
||||
python plane_gw.py 20130 # stdout логи; для фона: pythonw или background-терминал
|
||||
```
|
||||
|
||||
Пуул подхватывает `plane_accounts.jsonl` из той же папки (или env `PLANE_ACCOUNTS=<путь>`).
|
||||
Опционально: env-переменная GW_KEY (имя собирается из chr-кодов, grep "GWKEY") — Bearer-ключ для удалённого доступа; локально работает без ключа (9router-модель).
|
||||
|
||||
**Проверка (ОБЯЗАТЕЛЬНА перед отдачей):**
|
||||
```bash
|
||||
curl http://127.0.0.1:20130/health # {"ok": true, "pool_live": N} — N>0!
|
||||
curl http://127.0.0.1:20130/v1/models # 10 моделей plane/*
|
||||
curl http://127.0.0.1:20130/admin/pool # статус каждого акка (active/used/err)
|
||||
|
||||
# живой completion:
|
||||
curl http://127.0.0.1:20130/v1/chat/completions -H "Content-Type: application/json" \
|
||||
-d '{"model":"plane/claude-sonnet-5","messages":[{"role":"user","content":"say OK"}]}'
|
||||
```
|
||||
|
||||
## ШАГ 4. ПОДКЛЮЧЕНИЕ В CLI
|
||||
|
||||
Любой OpenAI-совместимый клиент:
|
||||
```
|
||||
base_url: http://127.0.0.1:20130/v1
|
||||
api_key: *** # любой, если GW_KEY не задан
|
||||
model: plane/claude-sonnet-5 # префикс plane/ обязателен
|
||||
```
|
||||
|
||||
Примеры:
|
||||
- **opencode/OMP**: provider custom openai-compatible, base_url как выше
|
||||
- **Hermes**: `hermes config set` → custom_providers с base_url http://127.0.0.1:20130/v1
|
||||
- **Cline/Roo**: API Provider = OpenAI Compatible, те же поля
|
||||
|
||||
## ЭКСПЛУАТАЦИЯ
|
||||
|
||||
| Ситуация | Действие |
|
||||
|---|---|
|
||||
| Добавил акков в jsonl | `curl http://127.0.0.1:20130/admin/reload` (без рестарта) |
|
||||
| Все акки в пуле disabled | Дофармить `--bulk`, reload |
|
||||
| 429/кредиты кончились | Шлюз сам дизейблит акк и ротует; утром (00:00 UTC) кредиты сбрасываются — акк снова live после `/admin/reload` |
|
||||
| Сессии протухли (7 дней) | Перефармить; старые FULL_OK записи шлюз задизейблит по 401 автоматически |
|
||||
| Хочешь больше кредитов/день | 20 акков × 105 = 2100 кредитов/день |
|
||||
|
||||
## ПИТФОЛЫ (проверено на себе)
|
||||
|
||||
1. **НЕ используй app.plane.so для API** — 405 на всё, это SPA. Только api.plane.so (auth/rest) и pi.plane.so (AI).
|
||||
2. **CSRF обязателен** на sign-up и на POST к /api/* — без X-CSRFToken будет csrf_failure.html с кодом 200 (ложный успех!). Проверяй Location на error_code.
|
||||
3. **Gmail +alias**: To-header в письме закодирован — перед матчем алиаса декодируй MIME (в combo уже сделано).
|
||||
4. **Код в SUBJECT**, не в теле: `login code is (\d{6})`.
|
||||
5. **dict(headers) схлопывает несколько Set-Cookie** → теряется session-id. Используй `headers.get_all("Set-Cookie")`.
|
||||
6. **queue-answer требует**: workspace_id + workspace_slug + chat_id + `context:{}` + mode. Без context → 422, без workspace → 400 "Workspace information is required".
|
||||
7. **stream SSE**: события `reasoning`/`delta`/`cta_available`/`done`. Бери только `delta.chunk`.
|
||||
8. **Троттл auth 10/min** — bulk sleep 7s не уменьшать.
|
||||
9. **/api/v1/ (X-API-Key)** — только CRUD проектов (work items и т.д.), чат НЕ отдаёт. Для чата — только pi.plane.so с cookie.
|
||||
10. Старые AI-эндпоинты (`ai-assistant/`, `rephrase-grammar/`) → 410 Gone, всё переехало на pi.plane.so.
|
||||
|
||||
## ФАЙЛЫ
|
||||
|
||||
```
|
||||
C:\Users\User\Desktop\_SCRIPTS\
|
||||
├── plane_full_combo.py # фарм: reg + workspace + api token (CONFIG заполни!)
|
||||
├── plane_gw.py # шлюз OpenAI-compat :20130
|
||||
├── plane_accounts.jsonl # пул (FULL_OK записи)
|
||||
└── PLANE_RUNBOOK.md # этот файл
|
||||
```
|
||||
|
||||
## TOOL USE + STREAMING (v2 шлюза)
|
||||
|
||||
**Streaming:** настоящий SSE-пасsthrough `delta`-событий pi.plane.so → OpenAI chunked format.
|
||||
Замечание: апстрим часто отдаёт ответ крупными дельтами (не по токену) — это поведение Plane, не шлюза.
|
||||
|
||||
**Tool calling:** pi.plane.so НЕ принимает клиентские tools (их тулы серверные: execute-action/artifacts/MCP).
|
||||
Шлюз ЭМУЛИРУЕТ OpenAI tool protocol:
|
||||
- инжектит схемы тулов в промпт со строгим JSON-протоколом (fenced ```json {"tool_calls":[...]}```)
|
||||
- StreamToolFilter вырезает tool-блоки из потока, остальные дельты идут клиенту сразу
|
||||
- возвращает настоящие OpenAI `tool_calls` + `finish_reason:"tool_calls"`
|
||||
- `role:"tool"` результаты из истории клиента сворачиваются обратно в промпт (stateless, полный транскрипт на каждый ход)
|
||||
|
||||
Проверено живьём 2026-09-20 (3 теста):
|
||||
1. sync + tools → `tool_calls:[get_weather {"city":"Paris"}]`, finish_reason=tool_calls ✓
|
||||
2. round-trip с tool result → финальный ответ "sunny in Paris 22°C", finish=stop ✓
|
||||
3. stream gpt-5.6-terra → SSE chunks + [DONE] ✓
|
||||
|
||||
Ограничение эмуляции: модель должна слушаться протокола (Claude/GPT — да; слабые модели могут отдавать тулы текстом — тогда фильтр пропустит их как обычный текст).
|
||||
Reference in New Issue
Block a user