autoreg-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok60915d52e8425
2026-10-20 02:16:32 +03:00
commit f58eafeb48
565 changed files with 60064 additions and 0 deletions

View File

@@ -0,0 +1,359 @@
---
name: conol-automation
description: Mass-register Conol.ai accounts via Chrome CDP, farm onboarding quests for credits, and run an OpenAI-compatible pool gateway across all accounts. Use when the user says "conol", "регистрируй", "сфарми квесты", "запусти шлюз", "авторег", or wants to scale Conol.ai API access.
category: automations
triggers:
- conol
- conol.ai
- авторег
- квесты conol
- шлюз conol
- масс регистрация conol
- пул аккаунтов
pitfalls:
- "httpx.AsyncClient SHARED across concurrent tasks corrupts cookies — every concurrent task MUST create its own `async with httpx.AsyncClient(cookies=cookies, ...)` block. Do NOT create one shared client and pass it to multiple tasks."
- "Conol.ai SSE events use `history_delta` type (NOT `text-delta`). Content is in `stages[].logs[].content[].text`. End event is `type: done`."
- "Direct `POST /api/chat` does NOT exist on Conol.ai. The correct protocol is: POST /api/sessions (create session) → GET /api/sessions/{id}/messages?logDeltas=1 (stream SSE)."
- "Conol cookies use `better-auth` tokens: `__Secure-better-auth.session_token` and `__Secure-better-auth.better-auth-passkey`. These expire and return HTTP 401 — re-login via Chrome CDP when that happens."
- "reCAPTCHA v3 on conol.ai is domain-locked. External solvers (2Captcha, AntiCaptcha, CapSolver) do NOT work. Must solve natively via Chrome CDP `page.evaluate(...)` calling `grecaptcha.execute(siteKey, {action})`."
- "⚠️ **RECAPTCHA v3 BLOCKED (2026-07-30):** conol.ai has stopped accepting recaptcha v3 tokens entirely. ALL registration attempts return `CAPTCHA_VERIFICATION_FAILED` (HTTP 403) regardless of token freshness or action. Tested: real Chrome CDP, 5+ action types, direct fetch() from browser context, form submit approaches — all fail. Root cause: server-side anti-bot detection (NOT token quality). Site key is `6Lc3wmAtAAAAAB9YBPXQtT9uGGsH3ul6LQBc5AUu`, signup endpoint is `/api/invites/register` with `x-captcha-response` header. Fallback: Google OAuth via signup page or manual browser registration. JS bundles show a new `/api/auth/register` endpoint exists in code but returns 404 on prod — not yet deployed."
- "HTTP 429 on verify-send means rate-limited. Increase inter-account delay (base 8s + 3s per account index)."
- "Model downgrades: when a requested model is overloaded, Conol.ai returns HTTP 201 with `modelDowngraded:true` and `effectiveModel` set to a fallback. Sessions still work — this is NOT an outage. Check the `modelDowngraded` field before assuming server-down."
- "FastAPI body parsing: `async def endpoint(request: dict)` does NOT parse JSON — FastAPI treats `dict` as query param type, returns None. Must use `from fastapi import Request` and `body = await request.json()`. See references/dashboard-multi-reg.md."
- "Windows port conflicts: dead processes leave ports occupied. Kill via `powershell -Command \"Stop-Process -Id <PID> -Force\"` — do NOT use `taskkill //PID` in git-bash (syntax fails)."
- "Tool call deduplication: Conol.ai SSE may emit duplicate tool_call events (same name + args, different stage IDs). Deduplicate by (name, json.dumps(input)) key. See references/conol-tool-use.md."
- "Tool + text coexistence: Conol.ai models return BOTH text AND tool_calls in same SSE response. OpenAI convention is content:null when tool_calls present. Filter content when tool_calls non-empty for strict OpenAI clients."
---
# Conol.ai Full Automation
Fully autonomous system for Conol.ai account management: registration → quest farming → API gateway.
## Quick Start
```bash
cd C:\Users\User\Desktop\conol_autoreg
USE_PYTHON="/c/Users/User/AppData/Local/Programs/Python/Python311/python.exe"
# Check pool status
$USE_PYTHON eni_conol.py status
# Register N accounts (⚠️ currently blocked by conol.ai anti-bot, see pitfalls)
$USE_PYTHON eni_conol.py reg 5
# Farm quests on all accounts
$USE_PYTHON eni_conol.py quests
# Start API gateway (port 9999)
$USE_PYTHON eni_conol.py gateway
# Multi-threaded registration from email queue (v2.0 — detailed errors)
$USE_PYTHON multi_reg.py 3 2
# Full cycle: register + quests + gateway
$USE_PYTHON eni_conol.py all 10
# Test all accounts for liveness
$USE_PYTHON eni_conol.py test
```
## Auto-Repair Daemon
Self-healing daemon that monitors all accounts, detects Conol.ai outages, and auto-recovers. Full docs: `references/auto-repair-daemon.md`.
**What it does every cycle (default 5 min):**
1. Health-checks all accounts (parallel, semaphore=5)
2. Detects server-wide outages (>80% HTTP 500) → skips repairs, logs `server_down`
3. Individual repairs: re-login via CDP on 401/cookie errors, re-register on dead cookies
4. Auto-farms quests when credits < 100
5. Restarts gateway if dead
**When to use:**
- Gateway keeps dying → daemon auto-restarts it
- Accounts losing credits → daemon auto-farms
- Conol.ai backend goes down → daemon detects and waits, then auto-recovers
## Architecture (2026-07-30)
```
conol_autoreg/
├── eni_conol.py # Master orchestrator (575 lines) — reg, quests, gateway, status, test
├── gateway.py # OpenAI-compatible pool gateway v6.1 (697 lines) — streaming + tool use
├── multi_reg.py # Multi-threaded parallel registration v2.0 (411 lines) — detailed errors
├── config.json # All settings (password, Gmail, CDP, port, site_key)
├── conol_accounts_pool.jsonl # Account database (~31 accounts)
├── email_queue.jsonl # Email queue for multi-threaded registration
├── cookies_*.json # Session cookies per account (~31 files)
├── chrome_cdp.bat # Chrome CDP launcher
└── start_all.bat # Unified launcher with menu
```
**Removed** (2026-07-30 cleanup): `dashboard_server.py`, `eni_repair_daemon.py`, `quests.py`, `config.example.json`, state JSON files. Gateway v6.1 features: token-level SSE streaming (10-30ms micro-delay), XML-based tool use emulation, round-robin pool with automatic failover.
## Registration Flow (Chrome CDP)
1. `page.clear_cookies()` + clear localStorage/sessionStorage
2. Navigate to `/sign-up`
3. Solve reCAPTCHA v3 natively: `grecaptcha.execute('6Lc3wmAtAAAAAB9YBPXQtT9uGGsH3ul6LQBc5AUu', {action: 'sign_up'})`
4. `POST /api/invites/register` with captcha in `x-captcha-response` header
5. `POST /api/auth/send-verification-email`
6. IMAP wait for verification email (Gmail: `[REDACTED-NAME]@gmail.com`, App Password in config)
7. `GET /api/auth/verify-email?token=[REDACTED]
8. Login: `POST /api/auth/sign-in/email`
9. Extract cookies → save as `cookies_<name>.json`
10. Append to `conol_accounts_pool.jsonl`
**Chrome CDP command:**
```
chrome.exe --remote-debugging-port=9228 --user-data-dir=C:\Users\User\Desktop\conol_chrome_profile
```
## Quest Farming
Six onboarding quests worth ~300 credits each:
| Quest ID | Action | Credit |
|----------|--------|--------|
| `note_written_by_agent` | Create note "ENI Log" | ~300 |
| `memory_written` | Save to persistent memory | ~300 |
| `note_edited_by_agent` | Edit the note | ~300 |
| `timer_scheduled` | Schedule a timer | ~300 |
| `note_shared` | Share note publicly | ~300 |
| `skill_installed` | Install from marketplace | ~300 |
Each quest is triggered by sending a prompt to `/api/sessions` with `gpt-5.6-luna` and `agentEffort: low`.
## Gateway API
OpenAI-compatible endpoint at `http://127.0.0.1:9999/v1/chat/completions`.
```bash
curl http://127.0.0.1:9999/v1/chat/completions \
-H "Authorization: Bearer test" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.5","messages":[{"role":"user","content":"Hello"}]}'
```
Endpoints:
- `GET /health` — pool status
- `GET /v1/models` — list 18 models
- `POST /v1/chat/completions` — chat (streaming + non-streaming + tool use)
- `POST /v1/images/generations` — SVG generation via Claude
- `GET /pool/stats` — per-account stats
- `POST /pool/reload` — hot-reload accounts file
18 models available — 5 support image/SVG generation (claude-opus-4-8, claude-fable-5, claude-opus-4-7, gemini-3-pro, gemini-3-flash).
## Tool Use (v6.1 — XML Emulation)
Gateway supports OpenAI-compatible tool calling via **XML emulation**. Conol.ai models have built-in tools (WebSearch, Fetch, SetIntention) but do **NOT** natively accept user-defined `tool_calls`. Instead:
1. Tool definitions are injected into the system prompt as XML schema
2. Gateway parses model responses for `<function_call>` XML tags
3. Emits standard OpenAI-format `tool_calls[]` in the response
**Verified working** (2026-07-30): `get_weather({"city": "London"})` on `gpt-5.6-luna` — finish_reason: `tool_calls`.
```bash
curl http://127.0.0.1:9999/v1/chat/completions \
-H "Authorization: Bearer test" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-luna",
"messages": [{"role": "user", "content": "Weather in London?"}],
"tools": [{"type": "function", "function": {"name": "get_weather", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}}}}],
"stream": false
}'
```
Both streaming and non-streaming modes support tool calls. Tool results can be sent back via `role: "tool"` messages for multi-turn tool loops.
Full protocol: `references/conol-tool-use.md`.
## Hermes Integration
Once the gateway is running, add it as a Hermes provider. See also `apioid-gateway` skill for the ApiOid production gateway ([REDACTED-NAME].loc.cc) — this Conol pool runs on port 9999 as a SEPARATE gateway, not the main ApiOid one.
Follow the full integration workflow:
→ `ai-config-optimization → references/provider-sync-workflow.md`
**Quick checklist (Conol-specific):**
| # | File | What to add |
|---|------|-------------|
| 1 | `~/.omp/agent/providers.yml` | `hermes-conol` block (baseUrl: `http://127.0.0.1:9999/v1`, apiKey: [REDACTED]) |
| 2 | `~/.omp/agent/models.yml` | Same `hermes-conol` block |
| 3 | `~/.omp/agent/config.yml` | `hermes-conol/*` in enabledModels, `hermes-conol` in providerOrder |
| 4 | `production/gateway.py` | `"CONOL"` in upstream prefix tuple (line ~191) |
| 5 | `production/run_gateway.ps1` | `UPSTREAM_CONOL_URL` + `UPSTREAM_CONOL_KEY` env vars |
| 6 | `update_all_providers.py` | `'hermes-conol'` entry in `updates` dict |
All 6 files must be updated. Gateway restart required after changes.
## Startup — Critical: Use System Python, NOT Hermes venv
The Hermes agent venv (`C:\Users\User\AppData\Local\hermes\hermes-agent\venv\`) has BROKEN pydantic_core and greenlet. Running the gateway or registration scripts inside it will crash immediately with:
```
ModuleNotFoundError: No module named 'pydantic_core._pydantic_core'
ModuleNotFoundError: No module named 'greenlet._greenlet'
```
The Windows Store `python3` (3.14) also has broken playwright greenlet.
**ALWAYS use system Python 3.11:**
```bash
/c/Users/User/AppData/Local/Programs/Python/Python311/python.exe eni_conol.py gateway
```
Or equivalently in batch:
```
C:\Users\User\AppData\Local\Programs\Python\Python311\python.exe eni_conol.py gateway
```
Do NOT use bare `python` or `python3` — they may resolve to the broken venv or Windows Store Python.
**If `python` otherwise works for you but Hermes venv crashes**, explicitly start with:
```bash
/c/Users/User/AppData/Local/Programs/Python/Python311/python.exe gateway.py
```
## Conol.ai Backend Outage (HTTP 500 on /api/sessions)
When ALL accounts return HTTP 500 from `POST /api/sessions` with `{"error":"Failed to create session"}`, this is a **Conol.ai server-side outage** — NOT a cookie/auth/code issue.
**Differential diagnosis — confirm server-down, not account issue:**
1. Test ONE account with valid payload → HTTP 500 = candidate outage
2. Test MULTIPLE models (gpt-5.5, claude-opus-4-8, gemini-3-flash, etc.) → ALL 500 = confirmed server-wide
3. Test with WRONG payload (missing required fields) → HTTP 400 (not 500) proves endpoint routing works, only session creation is broken
4. Test RSC endpoint: `GET https://conol.ai` with headers `Accept: text/x-component, RSC: 1` → also returns 500 HTML error page during server-side Next.js outages
5. Verify cookies valid: `GET /api/auth/get-session` → HTTP 200 confirms auth works, isolated to session creation
**The auto-repair daemon handles this automatically:** it detects >80% 500 failures and skips all repairs, logging `server_down`. When the backend recovers (sessions return 201), it logs `server_up` and resumes normal repair cycle. No manual intervention needed — just keep the daemon running.
**Manual verification (if daemon not running):**
```bash
/c/Users/User/AppData/Local/Programs/Python/Python311/python.exe -c "
import json, httpx
with open('cookies_conol066427.json') as f:
cookies = {c['name']: c['value'] for c in json.load(f)}
r = httpx.Client(cookies=cookies).post('https://conol.ai/api/sessions', json={
'source': {'type': 'home'}, 'messages': [{'type': 'text', 'content': 'OK'}],
'agentModel': 'gpt-5.5', 'agentEffort': 'low',
})
print(f'HTTP {r.status_code}: {r.text[:100]}')
"
```
If HTTP 201 and `sessionId` present → backend is alive. If HTTP 500 → wait and retry in 30-60 minutes.
## Model Downgrades (modelDowngraded: true)
When a requested model is unavailable or overloaded, Conol.ai silently downgrades to a fallback and returns `"modelDowngraded": true` with `"effectiveModel"` in the 201 session response. The session still works — it just uses a cheaper/smaller model. This is DIFFERENT from a server outage: with downgrades you get HTTP 201 + working sessions; with outages you get HTTP 500 for all models.
**Known downgrade paths observed in production:**
| Requested | Effective | When |
|-----------|-----------|------|
| `gpt-5.5` | `claude-haiku-4-5` | GPT-5.5 overload/outage (July 2026) |
**Detection:** Check `modelDowngraded` field in `POST /api/sessions` 201 response:
```json
{"sessionId":"j0c8y5kosm47bd1nsf2zlmrl","modelDowngraded":true,"effectiveModel":"claude-haiku-4-5"}
```
**Gateway impact:** The gateway forwards the response as-is — the `model` field in `/v1/chat/completions` response still shows the requested model (e.g. `gpt-5.5`), not the effective model. The downgrade is transparent to the caller. No code change needed.
**Important:** If you get 500 → wait (server outage). If you get 201 with `modelDowngraded: true` → the system works but the requested model is temporarily unavailable; you can still chat through the fallback model.
## Gateway Crash + Recovery
When Conol.ai returns 500 errors, the gateway accumulates `fail_count` on each account. After 5 failures, account is deactivated (`active = False`). When all accounts deactivate, the gateway exits with code 1.
**The auto-repair daemon handles this:** it health-checks the gateway every cycle and auto-restarts it (up to 3 attempts, 30s apart). It also reloads the pool after restart to pick up any account changes. Keep the daemon running and the gateway stays alive.
**Manual recovery (if daemon not running):**
1. Verify Conol.ai backend is alive (see above)
2. Restart gateway with matching API key:
```bash
# Old stable gateway (conol_github) — was stable for 20+ hours
cd C:\Users\User\Desktop\conol_github
ENI_POOL_KEY=test /c/Users/User/AppData/Local/Programs/Python/Python311/python.exe conol_pool_gateway.py
# New gateway (conol_autoreg) — uses config.json
cd C:\Users\User\Desktop\conol_autoreg
/c/Users/User/AppData/Local/Programs/Python/Python311/python.exe gateway.py
```
**API key must match OMP:** OMP at `~/.omp/agent/providers.yml` has `apiKey: [REDACTED] Gateway must run with that same key. The `conol_autoreg/config.json` has `gateway.api_key: test` (correct). The old `conol_github` gateway uses `ENI_POOL_KEY` env var — must be explicitly set.
## Common Pitfalls
### Python Interpreter (Hermes venv broken)
```bash
# ❌ WRONG — Python from Hermes venv (broken pydantic/greenlet)
python eni_conol.py gateway
# ❌ WRONG — Windows Store Python 3.14 (broken playwright greenlet)
python3 eni_conol.py gateway
# ✅ CORRECT — system Python 3.11
/c/Users/User/AppData/Local/Programs/Python/Python311/python.exe eni_conol.py gateway
```
### httpx Cookie Corruption
```python
# ❌ WRONG — shared client, cookies mix up
async with httpx.AsyncClient() as shared:
tasks = [test_with(shared, acc) for acc in accounts]
await asyncio.gather(*tasks)
# ✅ CORRECT — each task gets its own client
async def test_one(acc):
async with httpx.AsyncClient(cookies=acc_cookies, ...) as client:
...
```
### SSE Event Types
Conol.ai uses `history_delta` (NOT `text-delta`):
```python
if ev.get("type") == "history_delta":
for stage in ev.get("stages", []):
for log in stage.get("logs", []):
for c in log.get("content", []):
if c.get("text"):
full_text += c["text"]
```
### Account Liveness Check
Test each account by creating a session (HTTP 201 = alive):
```python
r = await client.post("https://conol.ai/api/sessions", json={
"source": {"type": "home"},
"messages": [{"type": "text", "content": "Say OK"}],
"timezone": "Europe/Kyiv",
"agentModel": "gpt-5.5",
"agentEffort": "low",
})
# 201 = alive, 401 = expired cookies
```
## Config
Key settings in `config.json`:
- `conol.password` — account password
- `gmail.address` / `gmail.app_password` — IMAP verification
- `cdp.url` — Chrome DevTools Protocol URL
- `gateway.port` / `gateway.api_key` — gateway settings
- `registration.*` — delays and timeouts
API key can be overridden via `ENI_POOL_KEY` environment variable.
## Dependencies
```
pip install httpx fastapi uvicorn playwright requests
playwright install chromium
```

View File

@@ -0,0 +1,54 @@
# Conol Self-Healing Auto-Repair Daemon
`eni_repair_daemon.py` — непрерывный мониторинг и авто-ремонт пула аккаунтов.
## Запуск
```bash
cd C:\Users\User\Desktop\conol_autoreg
python eni_repair_daemon.py # непрерывный демон (каждые 5 мин)
python eni_repair_daemon.py --once # разовый чек + ремонт
```
Из `start.bat`: пункты **7** (демон) и **8** (разовый).
## Фазы цикла
### Phase 1: Health Check
Проверяет `POST /api/sessions` на всех аккаунтах параллельно (5 конкурентов), timeout 15s.
### Phase 2: Server-Down Detection
Если >80% не-cookie ошибок = HTTP 500 → **пропускает весь ремонт**. Это conol.ai серверная проблема, не наши куки. Логируется `server_down`. Когда сервер оживает — `server_up`.
**Отличие от per-account ошибок:**
- 1-2 аккаунта 500 = индивидуальный сбой → repair
- 80%+ аккаунтов 500 = сервер мёртв → ждать
### Phase 3: Individual Repair
Аккаунт провалил `MAX_FAIL_STREAK=3` проверок подряд:
| Ошибка | Стратегия | Инструмент |
|--------|-----------|------------|
| HTTP 401 / "unauthorized" / "cookie" | Re-login через CDP | `relogin_account()` |
| "no_cookies" (статус 0) | Re-register | `eni_conol.py reg 1` |
### Phase 4: Credit Monitoring
Баланс < 100 cr → авто-фарм квестов на этом аккаунте.
### Phase 5: Gateway Health
Если гейтвей не отвечает → `taskkill` старого + запуск `gateway.py`. До 3 попыток с паузой 30s. После успешного перезапуска — `POST /pool/reload` для подхвата изменений.
## Логи и состояние
- `eni_repair_log.jsonl` — все события (health_ok, health_fail, repair_login, repair_farm, server_down, gateway_restart, ...)
- `eni_repair_state.json` — состояние между циклами (fail-счётчики, consecutive_server_downs, время последнего цикла)
## Пороги
| Параметр | Значение | ENV override |
|----------|----------|-------------|
| Интервал проверки | 300s (5 мин) | `ENI_REPAIR_INTERVAL` |
| Низкий баланс | < 100 cr | `CREDIT_LOW_THRESHOLD` |
| Мёртвый баланс | 0 cr | `CREDIT_DEAD_THRESHOLD` |
| Попыток до ремонта | 3 | `MAX_FAIL_STREAK` |
| Попыток перезапуска GW | 3 | `GATEWAY_RESTART_ATTEMPTS` |

View File

@@ -0,0 +1,66 @@
# Conol.ai Session 500 — Backend Outage Diagnosis
## Symptom
Gateway returns HTTP 502 `Conol error: session HTTP 500: {"error":"Failed to create session"}`.
Direct `httpx` to `POST /api/sessions` returns HTTP 500 on ALL accounts.
## Verify: Is it a backend outage or account issue?
```python
import json, httpx
# Test 3 different accounts
for fname in ['cookies_conol066427.json', 'cookies_conol127087.json', 'cookies_conol170189.json']:
with open(fname) as f:
cookies = {c['name']: c['value'] for c in json.load(f)}
client = httpx.Client(cookies=cookies, timeout=20)
# Auth check — should ALWAYS work if cookies are valid
r = client.get('https://conol.ai/api/auth/get-session')
user = r.json().get('user', {}) if r.status_code == 200 else {}
name = user.get('name', '?')
# Session create — THIS is what fails
r = client.post('https://conol.ai/api/sessions', json={
'source': {'type': 'home'},
'messages': [{'type': 'text', 'content': 'Say OK'}],
'agentModel': 'gpt-5.5',
'agentEffort': 'low',
})
print(f'{name}: auth={user.get("emailVerified")} | session HTTP {r.status_code} | {r.text[:100]}')
```
## Classification
| Auth `/get-session` | Session `/api/sessions` | Diagnosis | Action |
|-----|-----|-----|-----|
| 200 | 201 | ✅ Healthy | Normal operation |
| 200 | 500 | ❌ Backend outage | Wait 30-60 min, retry |
| 401 | 401 | ❌ Expired cookies | Re-login via Chrome CDP |
| 200 | 400 | ❌ Missing fields | Check payload format |
## Key insight
When `/api/auth/get-session` returns 200 (cookie is valid) but `/api/sessions` returns 500, this is 100% a **Conol.ai server-side issue**. The cookie/auth is fine — their session creation infrastructure is degraded.
Do NOT:
- Re-login accounts (unnecessary — cookies are valid)
- Change code (API format hasn't changed)
- Rotate cookies (won't help)
Just wait and retry.
## Recovery verification
```bash
# Quick test after waiting
curl -s -X POST http://127.0.0.1:9999/v1/chat/completions \
-H "Authorization: Bearer test" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.5","messages":[{"role":"user","content":"test"}],"max_tokens":5}'
```
If you see `"choices"` in response → backend recovered. If `"detail":"Conol error..."` → still down.

View File

@@ -0,0 +1,137 @@
# Conol.ai Tool Use Protocol
Gateway v6.0+ supports OpenAI-compatible tool calling through conol.ai's SSE API.
## Sending Tools to Conol.ai
Tools are passed in the session creation body as an Anthropic-format array:
```python
session_body = {
"source": {"type": "home"},
"messages": conol_msgs,
"timezone": "Europe/Kyiv",
"agentModel": model,
"agentEffort": "low",
"tools": [
{
"name": "get_weather",
"description": "Get current weather for a city",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}
],
}
```
Both Anthropic-format (`name`, `input_schema`) and OpenAI-format (`type: "function"`, `function: {name, parameters}`) are accepted by conol.ai. The gateway converts OpenAI format to Anthropic before sending.
## Receiving Tool Calls from SSE
Conol.ai emits tool calls as SSE `history_delta` events with `tool_call` log entries:
```json
{
"type": "history_delta",
"stages": [{
"id": "...",
"logs": [{
"role": "assistant",
"type": "tool_call",
"content": [{
"name": "WebSearch",
"type": "tool_call",
"input": {"query": "Paris weather"},
"result": [{"text": "83°F, Overcast..."}]
}]
}]
}]
}
```
Key fields:
- `name` — tool name (string)
- `input` — JSON arguments (dict)
- `result` — optional: array of `{"text": "..."}` objects with tool output
## Converting to OpenAI Format
```python
def conol_to_openai_tool_calls(events):
tool_calls = []
for ev in events:
if ev.tool_name:
tool_calls.append({
"id": f"call_{uuid.uuid4().hex[:8]}",
"type": "function",
"function": {
"name": ev.tool_name,
"arguments": json.dumps(ev.tool_input, ensure_ascii=False),
},
})
return tool_calls
```
## Built-in Tools (Auto-called by conol.ai)
Conol.ai models have built-in tools that fire automatically even when no user tools are provided:
| Tool | Purpose |
|------|---------|
| `WebSearch` | Web search via Exa.ai |
| `Fetch` | Fetch URL content with prompt |
| `SetIntention` | Internal meta-tool for task routing |
| `WriteNote` | Create Obsidian-style notes |
| `ReadNote` | Read persisted notes |
These appear in SSE as `tool_call` logs alongside any user-provided tools.
## Streaming Tool Calls
In streaming mode, tool calls are emitted as SSE chunks with `delta.tool_calls[]`:
```json
{
"object": "chat.completion.chunk",
"choices": [{
"delta": {"tool_calls": [{"id": "call_abc", "type": "function", "function": {"name": "WebSearch", "arguments": "{\"query\":\"...\"}"}}]},
"finish_reason": null
}]
}
```
Then final chunk with `finish_reason: "tool_calls"` or `"stop"`.
## Tool Result Loop (Tool → Model → Response)
To continue a conversation after tool calls, send tool results back as messages with `role: "tool"`:
```json
{
"model": "gpt-5.6-luna",
"messages": [
{"role": "user", "content": "Weather in Paris?"},
{"role": "assistant", "content": null, "tool_calls": [{"id": "call_1", "function": {"name": "get_weather", "arguments": "{\"city\":\"Paris\"}"}}]},
{"role": "tool", "tool_call_id": "call_1", "content": "83°F, Overcast"}
]
}
```
The gateway converts `role: "tool"` messages to text: `[Tool result #call_1]: 83°F, Overcast`.
## Pitfalls
### Duplicate Tool Calls
Conol.ai sometimes emits duplicate `tool_call` events in the SSE stream (same name, same arguments, different stage IDs). The gateway currently returns all of them. For production use, deduplicate by `(name, json.dumps(input))` key.
### Tool + Text in Same Response
Conol.ai models may return BOTH text content AND tool calls in the same response. OpenAI convention is `content: null` when tool_calls are present. The gateway currently returns both — downstream clients expecting strict OpenAI protocol may need `content: null` when `tool_calls` is non-empty.
### Tool Choice
`tool_choice: "auto"/"none"/"required"` is passed but conol.ai does not enforce strict tool choice — it always has its built-in tools available. For `tool_choice: "none"`, filter tool calls out in the gateway.
### Streaming + Tool Calls
When streaming with tools, conol.ai sends thinking text first, then tool calls, then final text. The gateway collects all events and emits tool calls first, then text. This causes a delay before the first chunk — the full response must arrive before streaming begins. Future improvement: buffer and emit as events arrive.

View File

@@ -0,0 +1,124 @@
# Dashboard + Multi-Reg System
New components added 2026-07-30 for the Conol pool distribution package.
## Architecture additions
```
conol_autoreg/
├── dashboard_server.py # FastAPI live dashboard (15 KB) — port 9988
├── multi_reg.py # Multi-threaded parallel registration (20 KB)
├── start_all.bat # Unified launcher with menu (3.3 KB)
├── chrome_cdp.bat # Chrome CDP launcher (667 B)
├── config.example.json # Template config for distribution (734 B)
├── requirements.txt # Python dependencies
└── README.md # User-facing guide (3 KB)
```
## Dashboard (port 9988)
FastAPI server with dark HTML interface, auto-refresh every 3s.
**API endpoints:**
- `GET /api/status` — full pool + gateway status
- `GET /api/accounts` — account list
- `GET /api/queue` — email queue
- `POST /api/queue/add` — add email to queue (JSON body: `{email, password}`)
- `POST /api/reload` — signal gateway to reload accounts
- `GET /api/queue/clear` — clear queue
**HTML interface features:**
- Stats cards: Alive, Dead, Total Credits, Avg Credits, Reg Today, Gateway
- Full account table with credits bars
- Email queue section with add form
- Action buttons: Refresh, Start Registration, Farm Quests, Reload Gateway
**Startup:**
```bash
python dashboard_server.py
# → http://127.0.0.1:9988
```
## Multi-Threaded Registration (multi_reg.py)
Reads `email_queue.jsonl`, registers N accounts per email in parallel.
**Usage:**
```bash
python multi_reg.py 3 2
# 3 = accounts per email
# 2 = max parallel threads
```
**Flow per email:**
1. Uses Chrome CDP via Playwright (`connect_over_cdp`)
2. `asyncio.Semaphore` controls concurrency
3. Per account: signup → recaptcha → send verification → IMAP wait → verify → login
4. Saves cookies → appends to `conol_accounts_pool.jsonl`
5. After registration: auto-farms all 6 quests
6. Updates `email_queue.jsonl` status: `queued` → `registering` → `registered` → `quests_done`
**Gmail verification** runs in `ThreadPoolExecutor` (parallel across clients):
```python
loop.run_in_executor(None, wait_for_verify_link_sync, gmail_addr, gmail_app, alias, since_epoch)
```
## Unified Launcher (start_all.bat)
Single `.bat` with 9-option menu:
1. Start Gateway (9999)
2. Start Dashboard (9988)
3. Start BOTH + Chrome CDP
4. Start Multi-Reg (from email queue)
5. Start ALL (Gateway + Dash + CDP)
6. Register N accounts (manual)
7. Farm Quests (all accounts)
8. Check Status / Health
9. Kill All
Auto-checks: Python installed, deps available, config.json valid, Chrome CDP running, gateway alive.
## Distribution Package
For giving to other people:
1. They copy `conol_autoreg` folder (minus your `config.json`)
2. Copy `config.example.json` → `config.json`, fill their gmail + app password
3. Install deps: `pip install fastapi uvicorn httpx playwright requests pyyaml`
4. Install Chromium: `playwright install chromium`
5. Run `start_all.bat`
6. Dashboard opens at `http://127.0.0.1:9988`
7. Add emails via dashboard form → run multi_reg
## FastAPI Pitfall: Request Body Parsing
```python
# ❌ WRONG — FastAPI treats `request: dict` as query parameter
@app.post("/api/queue/add")
async def queue_add(request: dict):
email = request.get("email") # → None!
# ✅ CORRECT — use `from fastapi import Request` + await request.json()
from fastapi import FastAPI, HTTPException, Request
@app.post("/api/queue/add")
async def queue_add(request: Request):
body = await request.json()
email = body.get("email") # → works!
```
**Reason:** FastAPI only auto-parses JSON body into Pydantic models or when using `Body()`. A bare `dict` type annotation is treated as a query parameter, not a body parameter. The `Request` object's `.json()` method gives direct access.
## Port Conflict Resolution (Windows)
When a process dies but leaves port occupied:
```bash
# Find PID on port
netstat -ano | grep 9988
# Kill via PowerShell (taskkill fails in git-bash)
powershell -Command "Stop-Process -Id <PID> -Force"
```
Do NOT use `taskkill //PID` in git-bash — syntax fails. Use PowerShell `Stop-Process` instead.

View File

@@ -0,0 +1,72 @@
# Conol.ai Gateway — OMP Key Matching
## Problem
Gateway starts with a random API key but OMP expects a specific one.
## Architecture
```
OMP (providers.yml) Gateway (port 9999)
├─ apiKey: test → ├─ /health → api_key_prefix
└─ baseUrl: ...9999/v1 ├─ /v1/chat/completions → Bearer auth
└─ /v1/models → Bearer auth
```
If the keys don't match: OMP gets HTTP 401 → falls back to next provider → "hermes-conol" NEVER works.
## Two Gateways, Two Key Mechanisms
### Gateway v3 (conol_github/conol_pool_gateway.py)
Uses `ENI_POOL_KEY` env var. Old stable gateway (20+ hour uptime).
```bash
cd C:\Users\User\Desktop\conol_github
ENI_POOL_KEY=test /c/Users/User/AppData/Local/Programs/Python/Python311/python.exe conol_pool_gateway.py
```
If `ENI_POOL_KEY` is not set, generates random `sha256(os.urandom(32))[:32]` → OMP will fail.
### Gateway v4 (conol_autoreg/gateway.py)
Reads from `config.json` → `gateway.api_key`. Default: `test`.
```bash
cd C:\Users\User\Desktop\conol_autoreg
/c/Users/User/AppData/Local/Programs/Python/Python311/python.exe gateway.py
```
Also respects `ENI_POOL_KEY` and `ENI_POOL_KEY_OVERRIDE` env vars (override priority: ENI_POOL_KEY_OVERRIDE > ENI_POOL_KEY > config.json).
## How to Verify Match
```bash
# Get gateway's actual key prefix
curl -s http://127.0.0.1:9999/health | python -c "import sys,json; print(json.load(sys.stdin)['api_key_prefix'])"
# Get OMP's expected key
python -c "
import yaml
with open(r'C:\Users\User\.omp\agent\providers.yml') as f:
c = yaml.safe_load(f)
print(repr(c['providers']['hermes-conol']['apiKey']))
"
```
Both should show `test...`.
## Common Failure Mode
Gateway was started without `ENI_POOL_KEY` → random key generated (e.g., `bfae749f...`). OMP has `test`. Result: OMP calls return 401, "hermes-conol" provider silently fails, all traffic falls back to echogate.
## Fix
1. Kill old gateway process
2. Restart with correct key:
```bash
# For conol_github gateway:
ENI_POOL_KEY=test python conol_pool_gateway.py
# For conol_autoreg gateway:
python gateway.py # reads test from config.json
```
3. OMP picks up immediately — no restart needed

View File

@@ -0,0 +1,50 @@
# httpx Concurrent Client Cookie Corruption
## Symptom
All 30 parallel requests return HTTP 401, but individual tests succeed.
## Root Cause
Sharing ONE `httpx.AsyncClient` instance across multiple concurrent `asyncio` tasks corrupts cookie handling. httpx reuses connection pools and cookie jars that are not thread/async-safe when multiple tasks set different cookies.
## Wrong Pattern
```python
# ❌ Creates one shared client — cookies from different accounts mix up
async def main():
async with httpx.AsyncClient(timeout=httpx.Timeout(30)) as shared_client:
# All 30 concurrent tasks use the SAME client
tasks = [test_account(shared_client, acc) for acc in accounts]
await asyncio.gather(*tasks)
async def test_account(client, acc):
# Setting cookies on the shared client
client.cookies = {name: value} # Gets overwritten by other tasks!
r = await client.post(...)
```
## Correct Pattern
```python
# ✅ Each concurrent task creates its OWN client
async def test_account(acc):
cookies = load_cookies(acc['cookies_path'])
async with httpx.AsyncClient(cookies=cookies, timeout=httpx.Timeout(30)) as client:
r = await client.post(...)
async def main():
tasks = [test_account(acc) for acc in accounts]
await asyncio.gather(*tasks)
```
## Concurrency Control
Use `asyncio.Semaphore(N)` to limit concurrent connections:
```python
sem = asyncio.Semaphore(3)
async def bounded(acc):
async with sem:
return await test_account(acc)
results = await asyncio.gather(*[bounded(a) for a in accounts])
```
## Detection
If you see HTTP 401 on all requests in parallel but HTTP 201 on individual sequential requests, this is almost certainly the shared client issue.

View File

@@ -0,0 +1,72 @@
# Conol.ai Model Downgrade Behavior
## Discovery Session: 2026-07-30
After a ~4-hour outage (all models returning HTTP 500 `"Failed to create session"`), Conol.ai backend recovered but with GPT-5.5 unavailable. Sessions that requested `gpt-5.5` were silently downgraded.
### Raw Observations
**Payload sent:**
```json
{
"source": {"type": "home"},
"messages": [{"type": "text", "content": "Say OK"}],
"timezone": "Europe/Kyiv",
"agentModel": "gpt-5.5",
"agentEffort": "low"
}
```
**Session created (HTTP 201):**
```json
{
"sessionId": "j0c8y5kosm47bd1nsf2zlmrl",
"modelDowngraded": true,
"effectiveModel": "claude-haiku-4-5"
}
```
**Full chat response:** Model still answered "OK" correctly — the downgrade is transparent to the caller.
### Test Matrix (6 payload variants, all HTTP 201)
| Variant | Status | modelDowngraded | effectiveModel |
|---------|--------|-----------------|----------------|
| full (tz + effort) | 201 | true | claude-haiku-4-5 |
| no timezone | 201 | true | claude-haiku-4-5 |
| bare (model only) | 201 | true | claude-haiku-4-5 |
| no model specified | 201 | true | claude-haiku-4-5 |
| no effort | 201 | true | claude-haiku-4-5 |
| source: direct | 201 | true | claude-haiku-4-5 |
**Key insight:** Even when NO model is specified (bare `source + messages`), Conol.ai downgrades to haiku. This means the downgrade is based on backend capacity, not the specific model requested.
### Gateway Transparency
The gateway (`gateway.py`) does NOT expose `modelDowngraded` or `effectiveModel` to the caller. The `/v1/chat/completions` response shows the original model name:
```json
{
"model": "gpt-5.5",
"choices": [{"message": {"content": "OK"}}]
}
```
The caller sees `model: "gpt-5.5"` even though haiku generated the response. This is acceptable — the alternative (returning actual model) would break downstream OMP provider matching.
### Distinguishing Downgrade from Outage
| Signal | Downgrade | Outage |
|--------|-----------|--------|
| HTTP status | 201 | 500 |
| `sessionId` | present | absent |
| `modelDowngraded` | `true` | N/A (no response) |
| `effectiveModel` | fallback model | N/A |
| Chat works | ✅ Yes | ❌ No |
| Action needed | None (transparent) | Wait + daemon auto-recovers |
### When This Matters
- **Don't panic on `modelDowngraded: true`.** It means the system works, just with a cheaper model.
- **Check `modelDowngraded` before assuming server-down.** If you test one account, get 201, and see `modelDowngraded: true` — the server is alive, only the model is downgraded.
- **The daemon correctly ignores downgrades.** It only triggers `server_down` on HTTP 500, not on `modelDowngraded`.

View File

@@ -0,0 +1,51 @@
# Conol.ai reCAPTCHA v3 Block — 2026-07-30
## Status: BLOCKED
conol.ai has stopped accepting reCAPTCHA v3 tokens for the `/api/invites/register` endpoint. All registration attempts through automated means (real Chrome CDP, fresh tokens, multiple actions) fail with `CAPTCHA_VERIFICATION_FAILED` (HTTP 403).
## Diagnostic steps taken
### 1. Token freshness test
- Generated 5+ fresh tokens via `grecaptcha.execute(siteKey, {action})` in real Chrome CDP
- All returned `CAPTCHA_VERIFICATION_FAILED`
- Site key: `6Lc3wmAtAAAAAB9YBPXQtT9uGGsH3ul6LQBc5AUu`
### 2. Action variation test
Tested actions: `sign_up`, `register`, `submit`, `signup`, `login`, `homepage`, `verify`, empty string
All failed identically with HTTP 403.
### 3. Fetch context test
Tested `fetch()` call from browser `page.evaluate()` context (real browser headers, cookies, Origin/Referer) — still 403.
### 4. Header test
- Without `x-captcha-response` header → 403
- With `x-captcha-response` header (fresh token) → 403
- With `x-turnstile-response` header → 403 (wrong captcha type)
### 5. JS bundle inspection
- Searched ALL Next.js chunks for captcha references
- Found no Turnstile, no hCaptcha, no client-side captcha at all
- reCAPTCHA v3 script loads in body but is invisible (no user interaction)
- New endpoint `/api/auth/register` found in JS bundles → returns 404 (not yet deployed)
### 6. Browser form test
- Filled signup form via real Chrome
- Form submit blocked by Next.js client-side validation
- `button[type="submit"]` disabled until checkbox checked
- Even with checkbox checked, no API calls triggered
- React fiber traversal (`__reactFiber` onClick) failed to trigger submission
## Root cause
Server-side anti-bot detection, NOT token quality. conol.ai backend rejects registrations based on fingerprint signals (IP reputation, request pattern, timing) regardless of captcha token validity.
## Current workaround status
**None working.** The 31 existing accounts in the pool (~24,800 credits) are functional for chat/API use through the gateway. New registrations require:
1. Manual browser registration (human solves whatever anti-bot conol.ai uses)
2. Google OAuth via signup page button
3. Wait for conol.ai to deploy their new `/api/auth/register` endpoint
## Impact on codebase
- `multi_reg.py v2.0` — properly reports `CAPTCHA_VERIFICATION_FAILED` with full error context
- `eni_conol.py reg N` — also fails with clear error messages
- Gateway remains fully operational with existing accounts

View File

@@ -0,0 +1,82 @@
# Native reCAPTCHA v3 via Chrome CDP
Conol.ai uses reCAPTCHA v3 (site key: `6Lc3wmAtAAAAAB9YBPXQtT9uGGsH3ul6LQBc5AUu`).
The captcha is **domain-locked** — external solvers (2Captcha, AntiCaptcha, CapSolver) do NOT work.
## Solution: Chrome CDP Native Execution
The browser already has the reCAPTCHA script loaded. Execute `grecaptcha.execute()` directly in the page context.
### Generic reCAPTCHA executor (playwright)
```python
async def recaptcha(page, action: str) -> str:
"""Execute reCAPTCHA v3 and return token."""
return await page.evaluate(
"""async ({siteKey, action}) => {
// Ensure grecaptcha is loaded
if (!window.grecaptcha) {
await new Promise((resolve, reject) => {
const old = document.getElementById('eni-recaptcha');
if (old) old.remove();
const script = document.createElement('script');
script.id = 'eni-recaptcha';
script.src = `https://www.recaptcha.net/recaptcha/api.js?render=${encodeURIComponent(siteKey)}`;
script.onload = resolve;
script.onerror = () => reject(new Error('recaptcha load failed'));
document.head.appendChild(script);
});
}
await new Promise((resolve) => window.grecaptcha.ready(resolve));
return await window.grecaptcha.execute(siteKey, {action});
}""",
{"siteKey": SITE_KEY, "action": action},
)
```
### Usage in registration flow
```python
# Step 1: Sign Up
signup_token = await recaptcha(page, "sign_up")
r = await json_fetch(page, "/api/invites/register", method="POST",
captcha=signup_token, body={...})
# Step 2: Send Verification Email
verify_token = await recaptcha(page, "send_verification_email")
r = await json_fetch(page, "/api/auth/send-verification-email", method="POST",
captcha=verify_token, body={...})
# Step 3: Sign In
signin_token = await recaptcha(page, "sign_in")
r = await json_fetch(page, "/api/auth/sign-in/email", method="POST",
captcha=signin_token, body={...})
```
### JSON fetch helper (via page.evaluate)
```python
async def json_fetch(page, path: str, *, method="GET", body=None, captcha=None):
"""Fetch API endpoint from page context (uses browser's cookies)."""
return await page.evaluate(
"""async ({path, method, body, captcha}) => {
const headers = {Accept: 'application/json'};
if (body !== null) headers['Content-Type'] = 'application/json';
if (captcha) headers['x-captcha-response'] = captcha;
const r = await fetch(path, {method, headers, credentials: 'include',
body: body === null ? undefined : JSON.stringify(body)});
const text = await r.text();
let data = null;
try { data = JSON.parse(text); } catch (_) {}
return {status: r.status, url: r.url, text: text.slice(0, 2000), data};
}""",
{"path": path, "method": method, "body": body, "captcha": captcha},
)
```
## Key Points
- Captcha token is sent via `x-captcha-response` header (NOT in body)
- Use `page.evaluate` to call browser APIs within the origin context
- Always clear cookies/storage between registrations to avoid session conflicts
- Increasing delays between accounts (8s + 3s per index) reduces HTTP 429 errors

View File

@@ -0,0 +1,104 @@
# Conol.ai SSE Protocol (Agent Sessions)
Conol.ai uses a custom SSE protocol over `/api/sessions`. This is NOT standard OpenAI SSE.
## Endpoints
### 1. Create Session
```
POST https://conol.ai/api/sessions
Content-Type: application/json
Cookies: __Secure-better-auth.session_token=<token>
__Secure-better-auth.better-auth-passkey=<key>
Body: {
"source": {"type": "home"},
"messages": [{"type": "text", "content": "user prompt"}],
"timezone": "Europe/Kyiv",
"agentModel": "gpt-5.5",
"agentEffort": "low"
}
Response: 201 Created
{
"sessionId": "dh2btg2juiqtjfuv5m02by2v"
}
```
### 2. Stream SSE Messages
```
GET https://conol.ai/api/sessions/{sessionId}/messages?logDeltas=1
```
## SSE Event Types
### `history_delta` — Main content event
This is the PRIMARY event type. Content is nested: `stages[] → logs[] → content[] → {type: "text", text: "..."}`
```json
{
"type": "history_delta",
"runtimeVersion": "orcai",
"stages": [{
"id": "hjbl6q...",
"logs": [{
"role": "assistant",
"type": "thinking",
"content": [{"type": "text", "text": "The user is asking..."}]
}],
"preview": [{
"role": "assistant",
"type": "thinking",
"content": [{"text": "..."}]
}]
}]
}
```
### `done` — End of stream
```json
{"type": "done"}
```
## Common Mistakes
### ❌ Looking for `text-delta` events
Conol.ai does NOT emit `text-delta`. All content comes via `history_delta`.
### ❌ Direct `POST /api/chat`
There is NO `/api/chat` endpoint. The only way to interact is through `/api/sessions`.
### ❌ Parsing only top-level content
Content is always nested: `stages[].logs[].content[]`. Must iterate through all levels.
## Correct Parser (Python)
```python
async with client.stream("GET", f"https://conol.ai/api/sessions/{sid}/messages?logDeltas=1") as stream:
async for line in stream.aiter_lines():
if not line or not line.startswith("data:"):
continue
ev = json.loads(line[5:].strip())
if ev.get("type") == "done":
break
if ev.get("type") == "history_delta":
for stage in ev.get("stages", []):
for log in stage.get("logs", []):
content = log.get("content", [])
if isinstance(content, list):
for part in content:
if isinstance(part, dict) and part.get("type") == "text":
full_text = part.get("text", full_text)
```
## Cookies
Conol.ai uses `better-auth` (not next-auth):
- `__Secure-better-auth.session_token` — session token
- `__Secure-better-auth.better-auth-passkey` — passkey
Both are `Secure`, `HttpOnly`, `SameSite=Lax`, domain `.conol.ai`.
Cookies expire and return HTTP 401 — re-login via Chrome CDP.